1. 示例程序 是一个控制台应用程序,程序实现了分别在主线程和后台线程并行执行,达到为数组赋值的效果。
可以中途停止后台线程。
2. 执行结果图片如下:
正常执行结束:
中途停止后台线程:
3.代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Threading; namespace BackgroundWorker多线程 { class DoBackgroundwork { BackgroundWorker bgWorker = new BackgroundWorker(); public int[] backArray{get;private set;} public bool CompletedNormally { get; private set; } //构造方法 public DoBackgroundwork(int[] array) { this.backArray = array; bgWorker.WorkerReportsProgress = true; bgWorker.WorkerSupportsCancellation = true; bgWorker.DoWork += DoWork_Handler; bgWorker.ProgressChanged += ProgressChanged_Handler; bgWorker.RunWorkerCompleted += RunWorkerCompleted_Handler; } public void StartWorker() { if (!bgWorker.IsBusy) { bgWorker.RunWorkerAsync(); } } public static int[] CalculateTheSequence(int[] array) { for (int i = 0; i < array.Length; i++) { array[i] = 10 * i; } return array; } public void DoWork_Handler(object sender, DoWorkEventArgs args) { BackgroundWorker worker = sender as BackgroundWorker; //进行后台计算 for (int i = 0; i < 10; i++) { //每一次迭代都检查是否已经取消 if (worker.CancellationPending) { args.Cancel = true; worker.ReportProgress(-1); break; } else { //如果没有被取消则继续计算 CalculateTheSequence(backArray); worker.ReportProgress((i+1)*10); //让程序慢点,这样可以输出得漂亮一点 Thread.Sleep(100); } } } //处理后台线程的输入 private void ProgressChanged_Handler(object sender,ProgressChangedEventArgs args) { string output = args.ProgressPercentage == -1 ? " Cancelled" : string.Format(" back: {0}% ", args.ProgressPercentage); Console.WriteLine(output); } //后台线程完成之后,总结并保存总和 private void RunWorkerCompleted_Handler(object sender,RunWorkerCompletedEventArgs args) { CompletedNormally = !args.Cancelled; } public void Cancel() { if(bgWorker.IsBusy) { bgWorker.CancelAsync(); } } } class Program { static void Main() { GiveInstructionsToTheUser(); OutputTheSummaryHeaders(); //创建并启动后台线程 int[] backArray=new int[10]; DoBackgroundwork bgw = new DoBackgroundwork(backArray); bgw.StartWorker(); //主线程启动计算,对每一次循环,检查用户是否已经取消了后台线程 //计算之后,进行短暂的休眠,这样程序可以慢一点,使得主线程不会比后台线程更快 int[] mainArray = new int[10]; for (int i = 0; i < 10; i++) { if (Program.CheckForCancelInput()) bgw.Cancel(); CalculateTheSequenceMain(mainArray); Thread.Sleep(100); Console.WriteLine("main: {0}%", (i + 1) * 10); } SummarizeResults(bgw, mainArray); Console.ReadLine(); } public static void GiveInstructionsToTheUser() { Console.WriteLine("本程序分别在主线程和后台线程并行计算两个数组的值。\n"); Console.WriteLine("第一次按下 <Enter> 键开始执行主线程main和后台线程back."); Console.WriteLine("第二次按下 <Enter> 键停止执行后台线程back."); Console.ReadLine(); } public static void OutputTheSummaryHeaders() { Console.WriteLine("------------------------"); } private static void SummarizeResults(DoBackgroundwork bgw, int[] mainArray) { Console.WriteLine("\n\n运行结果:"); Console.WriteLine("Main completed!"); for (int i = 0; i < mainArray.Length;i++ ) { Console.WriteLine("mainArray[" + i + "]: " + mainArray[i]); } if (bgw.CompletedNormally) { Console.WriteLine("\nBackground completed!"); for (int i = 0; i < bgw.backArray.Length; i++) { Console.WriteLine("backArray[" + i + "]: " + bgw.backArray[i]); } } else { Console.WriteLine("\nBackground Cancelled。"); } } public static bool CheckForCancelInput() { bool doCancel = Console.KeyAvailable; if (doCancel) Console.ReadKey(); return doCancel; } public static int[] CalculateTheSequenceMain(int[] array) { for (int i = 0; i < array.Length; i++) { array[i] = i * i; } return array; } } }
时间: 2024-11-10 15:18:12