(CLR via C#学习笔记)异步操作 - 线程池

一 线程池基础

1.线程池维护了一个操作请求队列,将请求的操作追加到线程池队列中,线程池的代码从队列中提取
操作项,派发给线程池中的线程;


2.CLR初始化时,线程池中是没有线程的,当有操作派发给线程池时,如果线程池中没有线程或者没有
空闲状态的线程,将会创建一个新的线程执行派发的操作,如果有空闲状态的线程,将直接派发一个
空闲状态的线程执行操作;


3.线程池线程完成操作任务后,线程不会被销毁,而是返回线程池,进入空闲状态,等待响应另一个派发请求;
4.当一个线程池线程处于空闲状态一段时间后(不同的CLR对这个时间定义不同),线程会自己醒来终止自己以释放内存资源.

 

示例代码:

 1 Console.WriteLine("主线程...");
 2 ThreadPool.QueueUserWorkItem(DoSomething, 5);
 3 Console.WriteLine("主线程继续执行...");
 4 
 5 static void DoSomething(object state)
 6         {
 7             Thread.Sleep(2000);
 8             int num = (int)state;
 9             Console.WriteLine("DoSomething..., Number:" + num);
10             return;
11         }

输出结果:  

主线程...    

主线程继续执行...

DoSomething..., Number:5

 

二 执行上下文

System.Threading命名空间有一个ExecutionContext类,它允许你控制线程的执行上下文如何

从一个线程"流"向另一个,默认情况下,CLR自动造成初始线程的志向上下文"流向"任何辅助线程.

示例代码:

 1 CallContext.LogicalSetData("Name", "Mike");
 2 //线程池线程可以访问逻辑调用上下文数据
 3 ThreadPool.QueueUserWorkItem(state => Console.WriteLine("Name:{0}", CallContext.LogicalGetData("Name")));
 4 
 5 //取消执行上下文在异步线程间的流动
 6 ExecutionContext.SuppressFlow();
 7 //线程池线程将不能访问逻辑调用上下文数据
 8 ThreadPool.QueueUserWorkItem(state => Console.WriteLine("Name:{0}", CallContext.LogicalGetData("Name")));
 9 
10 //恢复执行上下文在异步线程间的流动
11 ExecutionContext.RestoreFlow();
12 //...

执行结果:

Name:Mike

Name:

 

三 协作式取消

 1 //注册取消CancelationToken时调用的委托
 2 var cts = new CancellationTokenSource();
 3 cts.Token.Register(() => Console.WriteLine("The operation will be cancelled. -- 1"));
 4 cts.Token.Register(() => Console.WriteLine("The operation will be cancelled. -- 2"));
 5 
 6 //线程开始执行操作
 7 ThreadPool.QueueUserWorkItem(a => Count(cts.Token, 1000));
 8 
 9 Console.WriteLine("Please <Enter> to cancel the operation.");
10 Console.ReadLine();
11 
12 //传达取消请求
13 cts.Cancel();
14 
15 
16 //执行计数操作
17 static void Count(CancellationToken token, int countTo)
18 {
19     for (int i = 0; i < countTo; i++)
20     {
21         if (token.IsCancellationRequested)  //是否已请求取消
22         {
23             break;
24         }
25         Thread.Sleep(500);
26         Console.WriteLine(i);
27     }
28 }

说明: 键入"Enter"键,传达取消标识,Count计数操作结束,注册的两个委托方法得到执行. 

 

posted @ 2017-06-30 15:26  秒杀5S  阅读(262)  评论(0编辑  收藏  举报