C#多线程 BackgroundWorker类使用小例-控制台程序

来源:互联网 发布:淘宝茶叶店 编辑:程序博客网 时间:2024/06/06 12:26
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;        }    }}

0 0