C# 调度员-它是如何工作的?

C# 调度员-它是如何工作的?,c#,.net,windows,multithreading,C#,.net,Windows,Multithreading,在阅读了Dispatcher类的文档之后,我意识到它也可以用于非UI操作排队 那么Dispatcher类实际上是如何工作的呢?我知道,它的主要工作是将操作排队到特定的线程,但是它如何将这些操作“发送”到线程?线程如何“获取”这些操作 我最好的猜测是,每个线程都有某种“线程队列”,但我还是不知道。很显然,Dispatcher队列实现看起来像Win32消息泵,但它不是(尽管是)。让一个线程在另一个线程上启动代码执行不是一项简单的任务。问题的关键在于,您不能简单地告诉任何线程在该线程已经启动之后开始执

在阅读了
Dispatcher
类的文档之后,我意识到它也可以用于非UI操作排队

那么
Dispatcher
类实际上是如何工作的呢?我知道,它的主要工作是将操作排队到特定的线程,但是它如何将这些操作“发送”到线程?线程如何“获取”这些操作


我最好的猜测是,每个线程都有某种“线程队列”,但我还是不知道。

很显然,Dispatcher队列实现看起来像Win32消息泵,但它不是(尽管是)。

让一个线程在另一个线程上启动代码执行不是一项简单的任务。问题的关键在于,您不能简单地告诉任何线程在该线程已经启动之后开始执行一个方法。必须专门设置目标线程以提前接收此类请求

通常使用的模式是生产者-消费者。目标线程将围绕无限循环旋转,等待消息出现在阻塞队列中。队列设计为阻塞,直到队列中出现一个项目,从而防止目标线程不必要地消耗CPU时间。下面是一个非常简单的方法,让线程接受委托的注入以执行

public class Example
{
  private BlockingCollection<Action> queue = new BlockingCollection<Action>();

  public Example()
  {
    new Thread(
      () =>
      {
        while (true)
        {
          Action action = queue.Take();
          action();
        }
      }).Start();
  }

  public void ExecuteAsync(Action action)
  {
    queue.Add(action);
  }
}
公共类示例
{
私有BlockingCollection队列=新建BlockingCollection();
公共示例()
{
新线程(
() =>
{
while(true)
{
Action=queue.Take();
动作();
}
}).Start();
}
public void ExecuteAsync(操作)
{
添加(操作);
}
}
现在,在UI线程的情况下,它已经有一个消息循环在运行,因此
Dispatcher
类可以简单地向包含要执行的委托的消息队列发布一条特殊消息。在处理所有的油漆、按钮点击等的过程中,这个特殊的消息也会被UI线程拾取,并且它将开始执行委托。 那么Dispatcher类实际上是如何工作的呢?我知道, 它的主要工作是将操作排队到一个特定的线程,但是如何排队呢 它会将这些操作“发送”到线程吗

通过将委托排队到目标线程监视的队列中

线程如何“获取”这些操作

通过运行监视队列的无限循环。队列通常是一种称为阻塞队列的特殊类型,如果队列为空,它将阻塞使用线程

我最好的猜测是,每个线程都有某种“线程队列” 线,但我还是不知道


非常接近。除了线程实际上没有用于此目的的内置队列之外。它必须手动设置。这就是为什么只有经过专门设计的线程才能接受委托注入。UI线程是这样设置的,因为
Application.Run
会创建消息循环。在我的示例中,您将看到我必须使用
BlockingCollection
和无限循环使其在工作线程上工作。

这是一个非常有趣的问题,但您不需要一个窗口来拥有消息队列,这些是独立的概念,您可以通过调用peek message在任何线程上创建消息队列


当然,这并不意味着没有窗口的调度器有任何用处。我可以假设设计者考虑的是一个独立的Dispatcher对象,以便让它处理应用程序所拥有的尽可能多的窗口。

您是在WPF或Silverlight的上下文中询问的吗?@JoeWhite,也不是。您也可以在非gui应用程序中使用
Dispatcher
。@ebb,您可以在没有gui的应用程序中使用它,但它实际上没有意义。。。有更多的工具可以做到这一点。调度器的设计考虑了用户界面场景。@ThomasLevesque,我的问题仍然存在。我知道,当在像WPF这样的gui应用程序中使用时,调度器只需将操作排队到消息队列。然而,由于一个普通的“非gui”线程没有这样的消息循环(至少据我所知不是这样),我对它是如何工作的感兴趣。有趣的问题。显然,Dispatcher必须使用Windows消息队列;但这不仅仅是因为Dispatcher添加了消息优先级,而这些优先级并不属于普通的ol消息队列。和线程,因此,如果您认为Dispatcher即使在非UI应用程序中也能工作,那么它必须做的不仅仅是包装消息队列。谢谢您的回答我完全理解生产者/消费者等概念。我要问的是
Dispatcher
在非gui应用程序中如何/为什么工作。目前,我正在查看实际的
Dispatcher
类的源代码,它似乎创建了一个“仅消息窗口”,因此也创建了一个消息循环,但再次。。我一点也不确定。