public void Start() { lock (_lock) { if (_state == WorkerState.Stopped) { _requestedState = _state = WorkerState.Running; _eventWaiter.Reset(); _workerTask = new Thread(() => { while (true) { if (_state == WorkerState.Stopped) { break; } bool haveMoreWork = false; if (_state == WorkerState.Running) { try { haveMoreWork = _workerJob(); } catch { _requestedState = _state = WorkerState.Stopped; _isFaulted = true; throw; } // Check if state has been changed in workerJob thread. if (_requestedState != _state && _requestedState == WorkerState.Stopped) { _state = _requestedState; break; } } if (!haveMoreWork || _state == WorkerState.Suspended) { _eventWaiter.WaitOne(Timeout.Infinite); } _state = _requestedState; } }); _workerTask.Name = Name; _workerTask.IsBackground = true; _workerTask.Start(); SpinWait.SpinUntil(() => _workerTask.IsAlive); } else { throw new InvalidOperationException("The worker is already started."); } } }
public void Start() { lock (_lock) { if (_state == State.Stopped) { _requestedState = _state = State.Running; _eventWaiter.Reset(); // http://blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx // prefer using Task.Factory.StartNew for .net 4.0. For .net 4.5 Task.Run is the better option. _workerTask = Task.Factory.StartNew(x => { while (true) { if (_state == State.Stopped) { break; } bool haveMoreWork = false; if (_state == State.Running) { haveMoreWork = _workerJob(); // Check if state has been changed in workerJob thread. if (_requestedState != _state && _requestedState == State.Stopped) { _state = _requestedState; break; } } if (!haveMoreWork || _state == State.Suspended) { _eventWaiter.WaitOne(Timeout.Infinite); } _state = _requestedState; } }, CancellationToken.None, TaskCreationOptions.LongRunning); SpinWait.SpinUntil(() => _workerTask.Status == TaskStatus.Running); } else { throw new InvalidOperationException("The worker is already started."); } } }