Пример #1
0
        /// <summary>
        /// Starts the thread.
        /// </summary>
        public void Start()
        {
            if (_currentState != BackgroundLoopState.None)
            {
                throw new InvalidOperationException("Unable to start thread: Illegal state: " + _currentState + "!");
            }

            //Ensure that one single pass of the main loop is made at once
            _mainLoopSynchronizeObject.Release();

            // Create stop semaphore
            if (_threadStopSynchronizeObject != null)
            {
                _threadStopSynchronizeObject.Dispose();
                _threadStopSynchronizeObject = null;
            }

            _threadStopSynchronizeObject = new SemaphoreSlim(0);

            //Go into starting state
            _currentState = BackgroundLoopState.Starting;

            _mainThread = new Thread(this.BackgroundLoopMainMethod)
            {
                IsBackground = true,
                Name         = this.Name
            };

            _mainThread.Start();
        }
Пример #2
0
        /// <summary>
        /// Stops this instance.
        /// </summary>
        public void Stop()
        {
            if (_currentState != BackgroundLoopState.Running)
            {
                throw new InvalidOperationException($"Unable to stop thread: Illegal state: {_currentState}!");
            }
            _currentState = BackgroundLoopState.Stopping;

            while (_taskQueue.TryDequeue(out _))
            {
            }

            //Trigger next update
            this.Trigger();
        }
Пример #3
0
        /// <summary>
        /// The thread's main method.
        /// </summary>
        private void BackgroundLoopMainMethod()
        {
            if (_mainThread == null)
            {
                return;
            }
            if (_mainThread != Thread.CurrentThread)
            {
                return;
            }

            try
            {
                _mainThread.CurrentCulture   = _culture;
                _mainThread.CurrentUICulture = _uiCulture;

                var stopWatch = new Stopwatch();
                stopWatch.Start();

                //Set synchronization context for this thread
                SynchronizationContext.SetSynchronizationContext(_syncContext);

                //Notify start process
                try
                {
                    CurrentBackgroundLoop = this;
                    this.OnStarting(EventArgs.Empty);
                }
                catch (Exception ex)
                {
                    this.OnThreadException(new BackgroundLoopExceptionEventArgs(_currentState, ex));
                    _currentState         = BackgroundLoopState.None;
                    CurrentBackgroundLoop = null;
                    return;
                }

                //Run main-thread
                if (_currentState != BackgroundLoopState.None)
                {
                    _currentState = BackgroundLoopState.Running;
                    while (_currentState == BackgroundLoopState.Running)
                    {
                        try
                        {
                            //Wait for next action to perform
                            _mainLoopSynchronizeObject.Wait(this.HeartBeat);

                            //Measure current time
                            stopWatch.Stop();
                            var elapsedTicks = stopWatch.Elapsed.Ticks;
                            stopWatch.Reset();
                            stopWatch.Start();

                            // Get current task queue
                            var localTaskQueue = new List <Action>();
                            while (_taskQueue.TryDequeue(out var dummyAction))
                            {
                                localTaskQueue.Add(dummyAction);
                            }

                            // Execute all tasks
                            foreach (var actTask in localTaskQueue)
                            {
                                try
                                {
                                    actTask();
                                }
                                catch (Exception ex)
                                {
                                    this.OnThreadException(new BackgroundLoopExceptionEventArgs(_currentState, ex));
                                }
                            }

                            // Performs a tick
                            this.OnTick(new BackgroundLoopTickEventArgs(elapsedTicks));
                        }
                        catch (Exception ex)
                        {
                            this.OnThreadException(new BackgroundLoopExceptionEventArgs(_currentState, ex));
                        }
                    }

                    // Notify stop process
                    try
                    {
                        this.OnStopping(EventArgs.Empty);
                    }
                    catch (Exception ex)
                    {
                        this.OnThreadException(new BackgroundLoopExceptionEventArgs(_currentState, ex));
                    }
                    CurrentBackgroundLoop = null;
                }

                // Reset state to none
                _currentState = BackgroundLoopState.None;

                stopWatch.Stop();
                stopWatch = null;
            }
            catch (Exception ex)
            {
                this.OnThreadException(new BackgroundLoopExceptionEventArgs(_currentState, ex));
                _currentState = BackgroundLoopState.None;
            }

            // Notify thread stop event
            try { _threadStopSynchronizeObject?.Release(); }
            catch (Exception)
            {
                // ignored
            }
        }
Пример #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BackgroundLoopExceptionEventArgs"/> class.
 /// </summary>
 /// <param name="threadState">The current state of the <see cref="BackgroundLoop"/>.</param>
 /// <param name="innerException">The inner exception.</param>
 public BackgroundLoopExceptionEventArgs(BackgroundLoopState threadState, Exception innerException)
 {
     this.Exception = innerException;
     this.State     = threadState;
 }