/* 线程池ThreadPool类会在需要时增减池中线程的线程数,直到最大的线程数。池中的最大线程数是可配置的。 在双核CPU中,默认设置为1023个工作线程和1000个I/O线程。也可以指定在创建线程池时应立即启动的最小线程数, 以及线程池,中可用的最大线程数。如果有更多的作业要处理,线程池中线程的个数也到了极限, 最新的作业就要排队,且必须等待线程完成其任务。 */ //下面这个方法是一个符合WaitCallBack委托的方法: static void WaitCallBackMethod(object param) { for (int i = 0; i < 5; i++) { Console.WriteLine(String.Format("Thread {0} is running", param)); Thread.Sleep(1000); } } //然后在主线程里给线程池添加方法,QueueUserWorkItem()方法的第二个参数是个object类型的参数,可传入一个数据到线程中 static void Main(string[] args) { for (int i = 1; i <= 3; i++) { ThreadPool.QueueUserWorkItem(WaitCallBackMethod, i); } Console.Read(); } ///////////////////////////////////////////////////////////////// //Task任务 1、Task类构造函数 使用Task类的构造函数。实例化Task对象时,任务不会立即运行,而是指定Created状态。 接着调用Task类的Start()方法来启动任务。 使用Task类时,除了调用Start()方法,还可以调用RunSynchronously()方法。 这样,任务也会启动,但是同时调用。默认情况下,任务是异步运行的。 Task类的构造函数接收一个无参无返回值的委托: Task task = new Task(TaskMethod); task.Start(); 下面是TaskMethod方法: static void TaskMethod() { for (int i = 0; i < 10; i++) { Console.WriteLine(String.Format("Running in a task. Task ID: {0}", Task.CurrentId)); Thread.Sleep(500); } } 方法里用Task.CurrentId属性取得当前任务ID。下面是主线程: static void Main(string[] args) { Task task = new Task(TaskMethod); task.Start(); for (int i = 0; i < 10; i++) { Console.WriteLine("Running in main thread."); Thread.Sleep(500); } Console.Read(); } 如果要往线程里传递参数,Task构造函数提供的重载,可以传入一个object类型的参数: Task task = new Task(TaskMethodWithParameter, "Hello world"); task.Start(); 下面是带参的线程方法: static void TaskMethodWithParameter(object param) { for (int i = 0; i < 10; i++) { Console.WriteLine(String.Format("Running in a task. Parameter: {0}", param)); Thread.Sleep(500); } } 2、TaskFactory类 使用实例化的TaskFactory类,在其中把TaskMethod方法传递给StartNew()方法,就会立即启动任务。 TaskFactory tf = new TaskFactory(); tf.StartNew(TaskMethod); 3、Task.Factory属性 Task类提供了一个Factory静态属性,这个属性返回一个TaskFactory对象。 Task task = Task.Factory.StartNew(TaskMethod); /////////////////////////////////////////////////////////////////////////////////// C#异步编程的实现方式——连续任务 通过任务,可以指定在任务完成后,应开始运行另一个特定任务。任务处理程序或者不带参数或者带一个对象参数,而连续处理程序有一个Task类型的参数。下面先定义两个任务: static void FirstTaskMethod() { Console.WriteLine(String.Format("Task {0} is doing something", Task.CurrentId)); Thread.Sleep(200); } static void SecondTaskMethod(Task task) { Console.WriteLine("Last task is finished"); Console.WriteLine(String.Format("Task {0} is doing something", Task.CurrentId)); Thread.Sleep(200); } 连续任务通过在任务上调用ContinueWith()方法来现实: static void Main(string[] args) { Task task1 = new Task(FirstTaskMethod); Task task2 = task1.ContinueWith(SecondTaskMethod); task1.Start(); for (int i = 0; i < 20; i++) { Console.WriteLine("Main thread is running"); Thread.Sleep(200); } Console.Read(); } 主线程循环输出字符串到控制台,Task1任务在另外一个线程里运行,FirstTaskMethod执行完继续SecondTaskMethod 值得注意的是,在一个任务结束时,可以启动多个任务,也就是说,任务的连接可以像一个树结构那样,如下代码: Task task1 = new Task(FirstTaskMethod); Task task2 = task1.ContinueWith(SecondTaskMethod); Task task3 = task1.ContinueWith(SecondTaskMethod); Task task4 = task2.ContinueWith(SecondTaskMethod); Task task5 = task2.ContinueWith(SecondTaskMethod); 无论前一个任务是如何结束的,后面的连续任务总是在前一个任务结束时启动。 TaskContinuationOptions枚举提供了OnlyOnFaulted,NotOnFaulted,OnlyOnCanceled, NotOnCanceled,OnlyOnRunToCompletion几个选项。我们可以指定只有当前一个任务成功结束时才启动: Task task5 = task2.ContinueWith(SecondTaskMethod, TaskContinuationOptions.OnlyOnRanToCompletion); /////////////////////////////////////////////////////////////////////////////////// C#异步编程的实现方式——层次任务 任务也可以构成一个层次结构。一个任务启动一个新任务时,就启动了一个层次结构。 下面的代码段在父任务内部新建一个任务。创建子任务的代码与创建父任务的代码相同, 唯一的区别是这个任务从另一个任务内部创建: static void Main(string[] args) { Task parentTask = new Task(ParentTask); parentTask.Start(); Console.Read(); } static void ParentTask() { Console.WriteLine("Parent task is starting"); Task childTask= new Task(ChildTask,TaskCreationOptions.AttachedToParent); childTask.Start(); Thread.Sleep(2000); Console.WriteLine("Parent task is finished"); } static void ChildTask() { Console.WriteLine("Child task started"); Thread.Sleep(4000); Console.WriteLine("Child task is finished"); } /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace Ex.RulesTester.Threads { /// <summary> /// Task异步等待所有线程结束通知测试 /// </summary> [TestClass] public class TaskAllCompleteTester { [TestMethod] public void TestTaskPoolStatus() { //运行异步多任务 TaskTest.RunTask(); var list = TaskTest.SuccessList; bool isAllComplete = false; //等待异步通知 while (!isAllComplete) { isAllComplete = TaskTest.IsAllComplete; list = TaskTest.SuccessList; } Assert.IsTrue(true); } /// <summary> /// 对于 task 多任务执行的封装 /// </summary> private class TaskTest { private static object m_lock = new object(); public static List<string> SuccessList = new List<string>(); private static string msg = ""; public static bool IsFinish = false; public static List<Task> TaskList = new List<Task>(); static bool isAllComplete = false; /// <summary> /// 标记所有任务是否全部执行完毕 /// </summary> public static bool IsAllComplete { get { return isAllComplete; } } private TaskTest() { } public static void RunTask() { //运行5个任务 for (int i = 1; i <= 5; i++) { var task = Task.Factory.StartNew(DoTask, i); TaskList.Add(task); } //异步等待所有任务执行完毕 Task.Factory.StartNew(x => { Task.WaitAll(TaskList.ToArray()); //标记所有任务运行完成 isAllComplete = true; }, null); } private static void DoTask(object par) { Thread.Sleep(int.Parse(par.ToString()) * 1000); lock (m_lock) { SuccessList.Add("Has Completed T" + par.ToString()); } } } } }