说明:希望通过揣摩这些案例,能进一步了解进程的工作原理。
1.方法一描述的是在同一窗口中,在计算素数的同时而不影响Canvas的工作。
方法1
1 #region Long-Running Calculation in UI Thread 2 3 public delegate void NextPrimeDelegate(); 4 private long num = 3; 5 private bool continueCalculating = false; 6 private bool fNotAPrime = false; 7 8 private void btnPrimeNumber_Click(object sender, RoutedEventArgs e) 9 {10 if (continueCalculating)11 {12 continueCalculating = false;13 btnPrimeNumber.Content = "Resume";14 }15 else16 {17 continueCalculating = true;18 btnPrimeNumber.Content = "Stop";19 20 //获取与此 System.Windows.Threading.DispatcherObject 关联的 System.Windows.Threading.Dispatcher21 22 //public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method);23 //按指定的优先级在与 System.Windows.Threading.Dispatcher 关联的线程上异步执行指定的委托。24 btnPrimeNumber.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber));25 26 }27 }28 29 public void CheckNextNumber()30 {31 // Reset flag.32 fNotAPrime = false;33 34 for (long i = 3; i <= Math.Sqrt(num); i++)35 {36 if (num % i == 0)37 {38 // Set not-a-prime flag to true.39 fNotAPrime = true;40 break;41 }42 }43 44 // If a prime number.45 if (!fNotAPrime)46 {47 tbPrime.Text = num.ToString();48 }49 50 num += 2;51 52 if (continueCalculating)53 {54 //3.In the CheckNextNumber function, because the first parameter55 //passed into BeginInvoke is DispatcherPriority.SystemIdle(在系统空闲时处理操作。), 56 //all of the CheckNextNumber workitem will not break the UI operation.57 58 btnPrimeNumber.Dispatcher.BeginInvoke(59 System.Windows.Threading.DispatcherPriority.SystemIdle,60 new NextPrimeDelegate(this.CheckNextNumber));61 }62 }63 64 #endregion
方法2
1 #region Blocking Operation in Worker Thread 2 3 private delegate void NoArgDelegate(); 4 private delegate void OneArgDelegate(Int32[] arg); 5 6 //1.When the Retrieve Data from Server button is clicked, the click handle retrieveData function is called. 7 private void btnRetrieveData_Click(object sender, RoutedEventArgs e) 8 { 9 this.btnRetrieveData.IsEnabled = false;10 this.btnRetrieveData.Content = "Contacting Server";11 12 NoArgDelegate fetcher = new NoArgDelegate(this.RetrieveDataFromServer);13 14 //2.Then our codes use delegate.BeginInvoke to start a thread from the thread pool.15 //This thread is used to perform the long operation of retrieving data.16 fetcher.BeginInvoke(null, null);17 }18 19 ///20 /// Retrieve data in a worker thread(辅助线程).21 /// 22 private void RetrieveDataFromServer()23 {24 //3.We use Thread.Sleep(5000) to simulate(模拟) a 5 seconds delay here.25 // Simulate the delay from network access.26 Thread.Sleep(5000);27 28 //4.The codes generate 4 random numbers as data and update them to the UI by calling the Dispatcher.BeginInvoke().29 30 // Generate random data to be displayed.31 Random rand = new Random();32 Int32[] data = {33 rand.Next(1000), rand.Next(1000), 34 rand.Next(1000), rand.Next(1000) 35 };36 37 // Schedule the update function in the UI thread.38 this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,39 new OneArgDelegate(UpdateUserInterface), data);40 41 }42 43 ///44 /// Update the UI about the new data. The function runs in the UI thread.45 /// 46 /// 47 private void UpdateUserInterface(Int32[] data)48 {49 this.btnRetrieveData.IsEnabled = true;50 this.btnRetrieveData.Content = "Retrieve Data from Server";51 this.tbData1.Text = data[0].ToString();52 this.tbData2.Text = data[1].ToString();53 this.tbData3.Text = data[2].ToString();54 this.tbData4.Text = data[3].ToString();55 }56 57 #endregion