文档详情

C# TaskScheduler任务调度器的实现.docx

发布:2025-05-29约7.42千字共9页下载文档
文本预览下载声明

C#?TaskScheduler任务调度器的实现

目录什么是TaskScheduler?TaskScheduler任务调度器的原理.net中的任务调度器有哪些一:ThreadPoolTaskScheduler二:SynchronizationContextTaskScheduler三:自定义TaskScheduler

什么是TaskScheduler?

SynchronizationContext是对调度程序(scheduler)的通用抽象。个别框架会有自己的抽象调度程序,比如System.Threading.Tasks。当Tasks通过委托的形式进行排队和执行时,会用到System.Threading.Tasks.TaskScheduler。和SynchronizationContext提供了一个virtualPost方法用于将委托排队调用一样(稍后,我们会通过典型的委托调用机制来调用委托),TaskScheduler也提供了一个abstractQueueTask方法(稍后,我们会通过ExecuteTask方法来调用该Task)。

通过TaskScheduler.Default我们可以获取到Task默认的调度程序ThreadPoolTaskScheduler线程池(译注:这下知道为什么Task默认使用的是线程池线程了吧)。并且可以通过继承TaskScheduler来重写相关方法来实现在任意时间任意地点进行Task调用。例如,核心库中有个类,名为System.Threading.Tasks.ConcurrentExclusiveSchedulerPair,其实例公开了两个TaskScheduler属性,一个叫ExclusiveScheduler,另一个叫ConcurrentScheduler。调度给ConcurrentScheduler的任务可以并发,但是要在构造ConcurrentExclusiveSchedulerPair时就要指定最大并发数(类似于前面演示的MaxConcurrencySynchronizationContext);相反,在ExclusiveScheduler执行任务时,那么将只允许运行一个排他任务,这个行为很像读写锁。

和SynchronizationContext一样,TaskScheduler也有一个Current属性,会返回当前调度程序。不过,和SynchronizationContext不同的是,它没有设置当前调度程序的方法,而是在启动Task时就要提供,因为当前调度程序是与当前运行的Task相关联的。所以,下方的示例程序会输出True,这是因为和StartNew一起使用的lambda表达式是在ConcurrentExclusiveSchedulerPair的ExclusiveScheduler上执行的(我们手动指定cesp.ExclusiveScheduler),并且TaskScheduler.Current也

usingSystem;

usingSystem.Threading.Tasks;

classProgram

staticvoidMain()

varcesp=newConcurrentExclusiveSchedulerPair();

Task.Factory.StartNew(()=

Console.WriteLine(TaskScheduler.Current==cesp.ExclusiveScheduler);

},default,TaskCreationOptions.None,cesp.ExclusiveScheduler)

.Wait();

}

TaskScheduler任务调度器的原理

publicabstractclassTaskScheduler

//任务入口,待调度执行的Task会通过该方法传入,调度器会将任务安排task到指定的队列(线程池任务队列(全局任务队列、本地队列)、独立线程、ui线程)只能被.NETFramework调用,不能配派生类调用

protectedinternalabstractvoidQueueTask(Tasktask);

//这个是在执行Task回调的时候才会被执行到的方法,放到后面再讲

protectedabstractboolTryExecuteTaskInline(Tasktask,booltaskWasPreviouslyQueued);

protectedabstractboolTryExecuteTask(Tas

显示全部
相似文档