NCindy

.net平台上的高性能网络程序开发框架

并发和协调运行时

原文链接

微软最近发布了为机器人编写应用的新的Microsoft Robotics Studio的预览版。这些新的工具很有趣,但是它应该比仅仅为机器人编程更加有趣。

 

Dispatcher类

当你的应用程序初始化的时候,你首先希望构造一个Dispatcher对象来管理一组线程。它实际上是一个线程池。和CLR的线程池一样,这些线程调用方法(通过delegate)来执行任务:

public sealed class Dispatcher : IDisposable {
    public Dispatcher();
    public Dispatcher(Int32 threadCount, String threadPoolName);
    public Dispatcher(Int32 threadCount, ThreadPriority priority,
        String threadPoolName);
    public ICollection<DispatcherQueue> DispatcherQueues { get; }
    ... // Other members not shown
}

当你构造Dispatcher对象时,可以把你想要的线程数传递给构造函数。在默认情况下,Dispatcher为每个CPU创建一个线程。注意,一个Dipatcher对象创建的线程数量是固定的,Dispatcher没有动态的创建或者销毁线程的逻辑。和CLR线程池不同,没有用来定期检查工作负载并动态调整线程池中线程数量的的特殊线程。这简化了Dispatcher线程池逻辑,并且使它更加高效。

当构造一个Dispatcher的时候,你还可以设定线程调度的优先级。默认情况下线程的优先级为普通。你还可以设置Dispatcher创建的线程的名称,当Dispatcher内部创建线程时,它会将线程对象的Name属性赋值为你设定的名字。这个名字可以帮助你进行调试,当你在Visual Studio中调试的时候还可以在线程窗口中看到它。

不像CLR中全局唯一的线程池,CCR允许你通过创建多个Dispatcher对象来创建多个线程池。这还使得你可以为不同类型的任务创建不同的线程池,如果你需要的话,还可以为每个线程池设定不同的优先级。

DispatcherQueue类

在你创建了一个Dispatcher之后,你将希望创建一个DispatcherQueue对象。一个DispatcherQueue维护了一个准备执行的delegate的队列。Dispatcher的线程等待有元素出现在DispatcherQueue中。通常DispatcherQueue是空的,并且Dispatcher的线程处于等待状态。当有元素出现时,Dispatcher线程苏醒,并且行该元素对应的方法。

public sealed class DispatcherQueue : IDisposable {
    // Use CLR thread pool; not Dispatcher
    public DispatcherQueue(string name); 
    public DispatcherQueue(String name, Dispatcher dispatcher);

    public virtual void Enqueue(ITask task);
    public virtual void EnqueueTimer(
        TimeSpan timeSpan, Port<DateTime> timerPort);
   
    public void Dispose();

    ... // Other members not shown
}

对于CLR的线程池,如果有1000个元素在排队,当这1000个元素被处理完之前你没有办法让一个新的元素被处理。但是在CCR中,你可以分配一个DispatcherQueue给大多数的工作项,同时分配另外一个DispatcherQueue对象给高优先级的工作项。Dispatcher对象轮循所有与之关联的DispatcherQueue,并从中取出元素。我还需要指出,如果在DispatcherQueue的构造函数中不带Dispatcher参数将可能会创建一个使用CLR线程池而不是Dispatcher的DispatcherQueue对象。

通常情况下,应用程序在初始化的时候构造Dispatcher和DispatcherQueue对象,并在程序余下的生命周期中使用它们。所以,现在我们把注意力转到那些应用程序常常构造、使用一小段时间然后就废弃的对象上。

Port和Arbiter类

一个泛型的Port<T>对象代表一个队列,队列中所有的元素类型都是T。你可以认为port是一种回调函数的参数队列,类似于ThreadPool.QueueUserWorkItem方法的state参数。

当异步操作完成,它的结果会投递到一个Port对象中。

posted on 2007-12-18 14:47  iceboundrock  阅读(409)  评论(0编辑  收藏  举报

导航