Developer, Former MVP, now at Microsoft - Best of 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
// Declare the worker private BackgroundWorker mBW; // Call this method in form's ctor private void InitBW(){ mBW = new BackgroundWorker(this); mBW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(mBW_RunWorkerCompleted); mBW.ProgressChanged += new ProgressChangedEventHandler(mBW_ProgressChanged); mBW.DoWork += new DoWorkEventHandler(mBW_DoWork); mBW.WorkerReportsProgress = true; mBW.WorkerSupportsCancellation = true; } // Handles click for Calc/Cancel button private void cmdCalc_Click(object sender, System.EventArgs e) { if (cmdCalc.Text == "Calc"){ // read digits from numeric updown control int digits = (int)nuDigits.Value; pbLeft.Maximum = digits; // ask worker to do its job mBW.RunWorkerAsync(digits); cmdCalc.Text = "Cancel"; }else if (cmdCalc.Text == "Cancel"){ // ask worker to cancel cmdCalc.Enabled = false; mBW.CancelAsync(); }else{ // Only two enabled states for // this button: Calc and Cancel System.Diagnostics.Debug.Assert(false); } } // Completion event private void mBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // Just get ready for next time cmdCalc.Text = "Calc"; cmdCalc.Enabled = true; } // Progress event private void mBW_ProgressChanged(object sender, ProgressChangedEventArgs e) { // Touch GUI, no problem pbLeft.Value = e.ProgressPercentage; txtPi.Text = (string)e.UserState; } // On worker thread! Only method with real logic private void mBW_DoWork(object sender, DoWorkEventArgs e) { int digits = (int)e.Argument; BackgroundWorker bw = (BackgroundWorker)sender; // we will be updating the UI with progress string pi = "3"; // Show progress (ignoring Cancel so soon) bw.ReportProgress(0, pi); if( digits > 0 ) { pi += "."; for( int i = 0; i < digits; i += 9 ) { // Work out pi. Scientific bit :-) int nineDigits = NineDigitsOfPi.StartingAt(i + 1); int digitCount = System.Math.Min(digits - i, 9); string ds = System.String.Format("{0:D9}", nineDigits); pi += ds.Substring(0, digitCount); // Show progress bw.ReportProgress(i + digitCount, pi); // Deal with possible cancellation if (bw.CancellationPending == true){ e.Cancel = true; break; } } } }