diff options
Diffstat (limited to 'Software/Visual_Studio/Tango.Core')
3 files changed, 121 insertions, 73 deletions
diff --git a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj index 8014ac3f2..605ba53dc 100644 --- a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj +++ b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj @@ -98,7 +98,7 @@ <Compile Include="IO\KnownFolders.cs" /> <Compile Include="Json\ProtobufContractResolver.cs" /> <Compile Include="Threading\ActionTimer.cs" /> - <Compile Include="Threading\SequencerThread.cs" /> + <Compile Include="Threading\IntervalMessageDispatcher.cs" /> <Compile Include="Threading\TaskSequencer.cs" /> <Compile Include="Threading\ThreadFactory.cs" /> <Compile Include="Threading\TimeoutTask.cs" /> @@ -206,7 +206,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> <Import Project="..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.108.0\build\net46\System.Data.SQLite.Core.targets')" /> diff --git a/Software/Visual_Studio/Tango.Core/Threading/IntervalMessageDispatcher.cs b/Software/Visual_Studio/Tango.Core/Threading/IntervalMessageDispatcher.cs new file mode 100644 index 000000000..ed61bea62 --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/Threading/IntervalMessageDispatcher.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Tango.Core.Threading +{ + /// <summary> + /// Represents a message queue dispatcher for delivering messages at a constant interval. + /// </summary> + /// <typeparam name="TMessage"></typeparam> + /// <seealso cref="System.IDisposable" /> + public class IntervalMessageDispatcher<TMessage> : IDisposable + { + private Thread _queueThread; + private ProducerConsumerQueue<TMessage> _queue; + private Action<TMessage> _onNext; + + /// <summary> + /// Gets or sets the interval. + /// </summary> + public int Interval { get; set; } + + /// <summary> + /// Gets a value indicating whether this instance has started. + /// </summary> + public bool IsStarted { get; private set; } + + /// <summary> + /// Gets the number of queued messages. + /// </summary> + public int Count + { + get { return _queue.Count; } + } + + /// <summary> + /// Initializes a new instance of the <see cref="IntervalMessageDispatcher{T}"/> class. + /// </summary> + /// <param name="onNext">The delivery callback.</param> + public IntervalMessageDispatcher(Action<TMessage> onNext) + { + _onNext = onNext; + _queue = new ProducerConsumerQueue<TMessage>(); + } + + /// <summary> + /// Starts the dispatching of messages. + /// </summary> + public void Start() + { + if (!IsStarted) + { + IsStarted = true; + _queueThread = new Thread(QueueThreadMethod); + _queueThread.Name = "Sequencer Thread"; + _queueThread.IsBackground = true; + _queueThread.Start(); + } + } + + /// <summary> + /// Pushes the specified message. + /// </summary> + /// <param name="message">The message.</param> + public void Push(TMessage message) + { + _queue.BlockEnqueue(message); + } + + private void QueueThreadMethod() + { + Stopwatch watch = new Stopwatch(); + watch.Start(); + + while (IsStarted) + { + watch.Restart(); + var item = _queue.BlockDequeue(); + + if (!IsStarted) break; + + try + { + _onNext?.Invoke(item); + } + catch { } + + Thread.Sleep(Math.Max(1, (int)(Interval - watch.ElapsedMilliseconds))); + } + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + public void Dispose() + { + IsStarted = false; + } + + /// <summary> + /// Creates a new instance of <see cref="IntervalMessageDispatcher{T}"/> and starts it immediately. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="onNext">The on next.</param> + /// <param name="interval">The interval.</param> + /// <returns></returns> + public static IntervalMessageDispatcher<T> StartNew<T>(Action<T> onNext, int interval) + { + IntervalMessageDispatcher<T> dispatcher = new IntervalMessageDispatcher<T>(onNext); + dispatcher.Interval = interval; + dispatcher.Start(); + return dispatcher; + } + } +} diff --git a/Software/Visual_Studio/Tango.Core/Threading/SequencerThread.cs b/Software/Visual_Studio/Tango.Core/Threading/SequencerThread.cs deleted file mode 100644 index 603790466..000000000 --- a/Software/Visual_Studio/Tango.Core/Threading/SequencerThread.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Tango.Core.Threading -{ - public class SequencerThread<T> : IDisposable - { - private Thread _queueThread; - private ProducerConsumerQueue<T> _queue; - private Action<T> _onNext; - - public int FrameRate { get; set; } - - public bool IsStarted { get; private set; } - - public SequencerThread(Action<T> onNext) - { - _onNext = onNext; - _queue = new ProducerConsumerQueue<T>(); - } - - public void Start() - { - if (!IsStarted) - { - IsStarted = true; - _queueThread = new Thread(QueueThreadMethod); - _queueThread.Name = "Sequencer Thread"; - _queueThread.IsBackground = true; - _queueThread.Start(); - } - } - - public void Push(T item) - { - _queue.BlockEnqueue(item); - } - - private void QueueThreadMethod() - { - Stopwatch watch = new Stopwatch(); - watch.Start(); - - while (IsStarted) - { - watch.Restart(); - var item = _queue.BlockDequeue(); - - if (!IsStarted) break; - - try - { - _onNext?.Invoke(item); - } - catch { } - - Thread.Sleep(Math.Max(1, (int)(FrameRate - watch.ElapsedMilliseconds))); - } - } - - public void Dispose() - { - IsStarted = false; - } - } -} |
