using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Text; using System.Threading; using System.Windows.Forms; namespace AsyncCalcPiSample { partial class AsyncCalcPiForm : Form { public AsyncCalcPiForm() { InitializeComponent(); } void ShowProgress(string pi, int totalDigits, int digitsSoFar) { // Make sure we're on the UI thread Debug.Assert(this.InvokeRequired == false); // Display progress in UI this.resultsTextBox.Text = pi; this.calcToolStripProgressBar.Maximum = totalDigits; this.calcToolStripProgressBar.Value = digitsSoFar; if( digitsSoFar == totalDigits ) { // Reset UI this.calcToolStripStatusLabel.Text = "Ready"; this.calcToolStripProgressBar.Visible = false; } // No need to force UI update when calculating asynchronously //this.Refresh(); } delegate void ShowProgressDelegate( string pi, int totalDigits, int digitsSoFar); void CalcPi(int digits) { StringBuilder pi = new StringBuilder("3", digits + 2); // Show progress //ShowProgress(pi.ToString(), digits, 0); // Get ready to show progress ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress); // Show initial progress asynchronously this.BeginInvoke( showProgress, new object[] { pi.ToString(), digits, 0 }); if( digits > 0 ) { pi.Append("."); for( int i = 0; i < digits; i += 9 ) { int nineDigits = NineDigitsOfPi.StartingAt(i + 1); int digitCount = Math.Min(digits - i, 9); string ds = string.Format("{0:D9}", nineDigits); pi.Append(ds.Substring(0, digitCount)); // Show continuing progress //ShowProgress(pi.ToString(), digits, i + digitCount); // Show continuing progress asynchronously this.BeginInvoke( showProgress, new object[] { pi.ToString(), digits, i + digitCount }); } } } delegate void CalcPiDelegate(int digits); void calcButton_Click(object sender, EventArgs e) { // Set calculating UI this.calcToolStripProgressBar.Visible = true; this.calcToolStripStatusLabel.Text = "Calculating..."; // Start pi calculation on new thread of execution //Thread piThread = new Thread(CalcPiThreadStart); //piThread.Start((int)this.decimalPlacesNumericUpDown.Value); // Begin calculating pi synchronously //CalcPiDelegate calcPi = new CalcPiDelegate(CalcPi); //calcPi((int)this.decimalPlacesNumericUpDown.Value); // Begin calculating pi asynchronously CalcPiDelegate calcPi = new CalcPiDelegate(CalcPi); calcPi.BeginInvoke( (int)this.decimalPlacesNumericUpDown.Value, // CalcPi argument EndCalcPi, // Called when CalcPi completes calcPi); // EndCalcPi argument (indirectly) } void EndCalcPi(IAsyncResult ar) { // Harvest results, re-thrown exceptions and clean-up resources try { CalcPiDelegate calcPi = (CalcPiDelegate)ar.AsyncState; calcPi.EndInvoke(ar); } catch( Exception ex ) { // EndCalcPi executed on worker thread //ShowProgress(ex.Message, 0, 0); // ERR! // Show error ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress); this.BeginInvoke( showProgress, new object[] { ex.Message, 0, 0 }); } } //void CalcPiThreadStart(object digits) { // // Convert thread start parameter to int // CalcPi((int)digits); //} } }