标签:
线程池基础
1,线程的创建和销毁是一个昂贵的操作,线程调度以及上下文切换耗费时间和内存资源。
2,线程池是一个线程集合,供应你的用程序使用。
3,每个CLR有一个自己的线程池,线程池由CLR控制的所有的AppDomain共享。
4,CLR初始化的时候,线程池没有线程的。
5,线程池维护一个操作请求队列。当应用程序想要执行一个一步操作的时候,就调用某个方法。将记录项(empty)追加到线程池队列中,然后线程池代码从队列中提取这个记录项,然后将记录项派遣(dispatch)给一个线程池的线程。当线程池线程完成任务后,不会被销毁。该线程会继续返回到线程池中,进入空闲状态,等待另一个请求。
6,多个应用程序向线程池发出多个请求的时候,只会尝试用一个线程来服务,当超过了线程池线程处理速度的时候,会创建额外的线程。
7,当线程池线程空闲一段时间之后,会自己醒来终止自己释放资源
8,线程池分为工作线程(worker)或者I/O线程,工作线程用于操作异步计算限制操作,I/O线程用于通知代码一个异步I/O限制操作已完成。异步编程模型:(Asychronous Programming Model APM)
执行简单的计算限制操作
计算限制操作:指需要长时间的计算的线程
1,要将一个异步,计算限制的操作放到线程池的队列中(向线程池添加一个“工作项”),调用ThreadPool类的几个方法:
static Boolean QueueUserWorkItem(WaitCallback callBack)
static Boolean QueueUserWorkItem(WaitCallback callBack,Object state)
2,线程池以异步调用一个方法
using System;
using System.Threading;
public static class Program{
public static void Main(){
Console.WriteLine("Main thread:queing an asynchronous operation");
TreadPool.QueueUserWorkItem(ComputeBoundOp,5);
Console.WriteLine("Main thread:Doing other work here....");
Thread.Sleep(10000);
Console.WriteLine("按任意键继续")
}
private static void ComputeBoundOp(Object state){
Consol.WriteLine("In ComputeBoundOp:state={0}",state);
Thread.Sleep(1000);//模拟其他工作1秒钟
}
}
执行上下文
1,每个线程都关联了一个执行上下文的数据结构
2,执行上下文包括:安全设置(压缩栈,Thread的Principal属性和windows身份),宿主设置(System.Treading.HostExcepitonContextManager)以及逻辑调用上下文数据(System.Runtime.Remoting.Messaging.CallContext的LogicalSetData和LogicalGetData)
3,线程执行代码有时候会受到执行上下文设置(安全设置居多)的影响
4,线程执行上下文可流动性。一个线程(初始线程)使用另一个线程(辅助线程)执行任务时,前者上下文应该流向(复制)辅助线程(耗性能).
5,阻止上下文的流动,可提高应用程序性能。
协作式取消
.net Framework提供了一套协作式取消模式,支持显示取消长时间运行的计算限制操作。
System.Thread.CancellationTokenSource对象:
public class CancellationTokenSource : IDisposable
{
//构造函数
public CancellationTokenSource();
//获取是否已请求取消此
System.Threading.CancellationTokenSource
public bool IsCancellationRequested { get; }
//获取与此 System.Threading.CancellationTokenSource 关联的 System.Threading.CancellationToken
public CancellationToken Token;
//传达取消请求。
public void Cancel();
//传达对取消的请求,并指定是否应处理其余回调和可取消操作。
public void Cancel(bool throwOnFirstException);
}
这个对象包含了管理取消有关的所有状态。构造好一个CancellationTokenSource(引 用类型)之后,可以从它的Token属性获得一个或多个CancellationToken(值类型)实 例,并传给你的操作,使那些操作可以取消。以下是CancellationToken值类型最有用 的一些成员:
public struct CancellationToken //一个值类型
{
//获取此标记是否能处于已取消状态,IsCancellationRequested 由非通过Task来调用(invoke)的一个操作调用(call)
public bool IsCancellationRequested { get; }
//如果已请求取消此标记,则引发 System.OperationCanceledException,由通 过Task来调用的操作调用
public void ThrowIfCancellationRequested();
//获取在取消标记时处于有信号状态的 System.Threading.WaitHandle,取消时, WaitHandle会收到信号
public WaitHandle WaitHandle { get; }
//返回空 CancellationToken 值。
public static CancellationToken None
//注册一个将在取消此 System.Threading.CancellationToken 时调用的委托。省略了简单重载版本
public CancellationTokenRegistration Register(Action<object> callback, object state, bool useSynchronizationContext);
//省略了GetHashCode、Equals成员
}
CancellationToken实例是一个轻量级的值类型,它包含单个私有字段:对它的CancellationTokenSource对象的一个引用。在一个计算限制操作的循环中,可以定时调用CancellationToken的IsCancellationRequested属性,了解循环是否应该提前终止,进而终止计算限制的操作。当然,提前终止的好处在于,CPU不再需要把时间浪费在你对其结果已经不感兴趣的一个操作上。
任务
ThreadPool的QueueUserWorkItem 存在限制,没有一个内建机制让你知道什么时候完成,也没有一个机制在操作完成返回一个值。
创建任务:
System.Threading.Tasks创建一个任务
创建Task任务调用的构造器,传递一个Action或者Action<Object>委托
取消任务:
用一个CancellationTokenSource取消一个Task。
一个任务完成时自动启动另一个新任务:
调用ContinuWith()使得一个Task完成时调用新的任务-------- wait方法会导致线程堵塞导致消耗性能
创建子任务:
Task<Int32[]> parent=new Task<Int32[]>(()=>{
var results=new Int32[3];
new Task(()=>results[0])=Sum(10000),TaskCreationOptions.AttacjedToParent).Start();
new Task(()=>results[0])=Sum(20000),TaskCreationOptions.AttacjedToParent).Start();
new Task(()=>results[0])=Sum(30000),TaskCreationOptions.AttacjedToParent).Start();
return results;
})
标签:
原文地址:http://www.cnblogs.com/changrulin/p/4786659.html