Code examples everywhere, but again, as a placeholder for me:
BackgroundWorker bw = new BackgroundWorker(); private void UserControl_Loaded(object sender, RoutedEventArgs e) { InitializeComponent(); bw.WorkerReportsProgress = true; bw.WorkerSupportsCancellation = true; bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); bw.RunWorkerAsync(); } private void bw_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; // do the time consuming operation }
using System.ComponentModel; needs to be included;
Now, the usual way to report progress in the time-consuming process is to use the following little snippet:
// in the time-consuming process, // where percent is a double with percentage complete worker.ReportProgress(percent); private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%"); }
Which is all well and good if you're just showing a progress bar or similar, but in my case I wanted to show an update of the components that had been processed, which was a text message. As the long-running thread is not on the GUI thread none of the GUI components can be directly touched as they go cross-thread so some alternatives are needed. The usual Silverlight route out of this is to use the dispatcher which works quite nicely:
// in the time-consuming process this.Dispatcher.BeginInvoke(delegate() { // do the GUI stuff in here } // back the time-consuming worker thread
And for the sake of completeness the usual way to enable cancellation of this thread is as follows:
// in the time-consuming process // periodically check if the thread has been // cancelled and break out, seeting e.Cancel if ((worker.CancellationPending == true)) { e.Cancel = true; }
this would be signalled in the GUI to set bw.CancellationPending = true. and the cancellation status would be passed through to the completion handler.
// and this can be used in the completed // handler if ((e.Cancelled == true)) { this.tbProgress.Text = "Canceled!"; } e.Cancel = true; }
Details of this and links to the rest of the BackgroundWorker methods are here.
No comments:
Post a Comment