示例#1
0
        /// <summary>
        /// Implements worker control, execution and delay logic in a loop.
        /// </summary>
        private void RunWorkerLoop()
        {
            while (WorkerState != WorkerState.Stopped && !IsDisposing && !IsDisposed)
            {
                CycleStopwatch.Restart();
                var interruptToken     = CycleCancellation.Token;
                var period             = Period.TotalMilliseconds >= int.MaxValue ? -1 : Convert.ToInt32(Math.Floor(Period.TotalMilliseconds));
                var delayTask          = Task.Delay(period, interruptToken);
                var initialWorkerState = WorkerState;

                // Lock the cycle and capture relevant state valid for this cycle
                CycleCompletedEvent.Reset();

                // Process the tasks that are awaiting
                if (ProcessStateChangeRequests())
                {
                    continue;
                }

                try
                {
                    if (initialWorkerState == WorkerState.Waiting &&
                        !interruptToken.IsCancellationRequested)
                    {
                        // Mark the state as Running
                        WorkerState = WorkerState.Running;

                        // Call the execution logic
                        ExecuteCycleLogic(interruptToken);
                    }
                }
                catch (Exception ex)
                {
                    OnCycleException(ex);
                }
                finally
                {
                    // Update the state
                    WorkerState = initialWorkerState == WorkerState.Paused
                        ? WorkerState.Paused
                        : WorkerState.Waiting;

                    // Signal the cycle has been completed so new cycles can be executed
                    CycleCompletedEvent.Set();

                    if (!interruptToken.IsCancellationRequested)
                    {
                        var cycleDelay = ComputeCycleDelay(initialWorkerState);
                        if (cycleDelay == Timeout.Infinite)
                        {
                            delayTask = Task.Delay(Timeout.Infinite, interruptToken);
                        }

                        ExecuteCycleDelay(
                            cycleDelay,
                            delayTask,
                            CycleCancellation.Token);
                    }
                }
            }

            ClearStateChangeRequests();
            WorkerState = WorkerState.Stopped;
        }
示例#2
0
        /// <summary>
        /// Executes the worker cycle control logic.
        /// This includes processing state change requests,
        /// the exeuction of use cycle code,
        /// and the scheduling of new cycles.
        /// </summary>
        private void ExecuteWorkerCycle()
        {
            CycleStopwatch.Restart();

            lock (SyncLock)
            {
                if (IsDisposing || IsDisposed)
                {
                    WorkerState = WorkerState.Stopped;

                    // Cancel any awaiters
                    try { StateChangedEvent.Set(); }
                    catch { /* Ignore */ }

                    return;
                }

                // Prevent running another instance of the cycle
                if (CycleCompletedEvent.IsSet == false)
                {
                    return;
                }

                // Lock the cycle and capture relevant state valid for this cycle
                CycleCompletedEvent.Reset();
            }

            var interruptToken     = CycleCancellation.Token;
            var initialWorkerState = WorkerState;

            // Process the tasks that are awaiting
            if (ProcessStateChangeRequests())
            {
                return;
            }

            try
            {
                if (initialWorkerState == WorkerState.Waiting &&
                    !interruptToken.IsCancellationRequested)
                {
                    // Mark the state as Running
                    WorkerState = WorkerState.Running;

                    // Call the execution logic
                    ExecuteCycleLogic(interruptToken);
                }
            }
            catch (Exception ex)
            {
                OnCycleException(ex);
            }
            finally
            {
                // Update the state
                WorkerState = initialWorkerState == WorkerState.Paused
                    ? WorkerState.Paused
                    : WorkerState.Waiting;

                lock (SyncLock)
                {
                    // Signal the cycle has been completed so new cycles can be executed
                    CycleCompletedEvent.Set();

                    // Schedule a new cycle
                    ScheduleCycle(!interruptToken.IsCancellationRequested
                        ? ComputeCycleDelay(initialWorkerState)
                        : 0);
                }
            }
        }