/// <summary> /// Work performed by a worker thread. /// </summary> /// <remarks> /// A worker thread executes the below until it receives a <see cref="PoisonPill"/>. /// </remarks> private void DoWork() { // Keep consuming until receive poison pill 'null' task while (true) { IWork workToBeProcessed; lock (this.queueLocker) { while (this.queue.Count == 0) { Monitor.Wait(this.queueLocker); } workToBeProcessed = this.queue.Dequeue(); if (ReferenceEquals(workToBeProcessed, POISON_PILL)) { // Poison pill received - this signals our exit break; } this.processing.Add(workToBeProcessed); } bool workSucceeded = false; string workFailedMsg = string.Empty; try { workToBeProcessed.Process(); workSucceeded = true; } catch (ApplicationException ex) { var message = string.Format("BackgroundWorkerQueue worker:{0}, Failed to process work:{1}", Thread.CurrentThread.Name, workToBeProcessed); workFailedMsg = message; } catch (Exception) { var message = string.Format("BackgroundWorkerQueue worker:{0}, Unexpected exception while processing work:{1}", Thread.CurrentThread.Name, workToBeProcessed); workFailedMsg = message; } lock (this.queueLocker) { this.processing.Remove(workToBeProcessed); if (workSucceeded) { var args = new WorkSucceededProcessingEventArgs(workToBeProcessed); this.OnWorkSucceeded(args); } else { this.HandleFailedWork(workToBeProcessed, workFailedMsg); } } } }
/// <summary> /// Fires the <see cref="WorkSucceeded"/> events if any are registered. /// </summary> /// /// <param name="e"> /// The arguments for the event. /// </param> private void OnWorkSucceeded(WorkSucceededProcessingEventArgs e) { // This is done to avoid a threading issue. var succeedEventListeners = this.WorkSucceeded; if (succeedEventListeners != null) { this.WorkSucceeded(this, e); } }
void OnWorkSucceed(object sender, WorkSucceededProcessingEventArgs e) { this.Called = true; }