/// <summary> /// The <see cref="BackgroundWorker.DoWork"/> event handler here waits on a semaphore if there /// are not status text items yet to process. If the semaphore has a non-zero value and we haven't /// been asked to close yet and there are pending status text items to be displayed, then we safely /// dequeue one and use the <see cref="BackgroundWorker.ReportProgress"/> event to notify the UI /// thread for this instance of the status text to display. We then wait for the minimum display /// timespan specified for the status text item before iterating. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { while (true) { // Wait on the semaphore, which will return if/as soon as there are status text items in // the queue or we've been allowed to close, otherwise will block indefinitely (no timeout). splashItemsSemaphore.WaitOne(); SplashStatusTextItem statusTextItem = null; // Safely attempt to retrieve an item from the queue. lock (this.synchronisationObject) { // If we're now allowed to close and there's nothing left in the queue then it's time to break. if (this.allowToClose && this.splashTextQueue.Count == 0) { break; } statusTextItem = this.splashTextQueue.Dequeue(); } // Use the report progress facility to communicate to this control's UI thread with the new status // text item to display. this.backgroundWorker.ReportProgress(0, statusTextItem); // If there's a non-zero timespan to keep the text displayed then sleep for that duration before continuing. if (statusTextItem.MinimumTimeSpanDisplayed > TimeSpan.Zero) { Thread.Sleep(statusTextItem.MinimumTimeSpanDisplayed); } } }
/// <summary> /// <see cref="BackgroundWorker.ProgressChanged"/> event handler which updates the status text label /// with the supplied status text as provided from the background worker thread. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { SplashStatusTextItem statusTextItem = (SplashStatusTextItem)e.UserState; this.labelStatus.Text = statusTextItem.Text; }