微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – Dispatcher – 它是如何工作的?

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

那么dispatcher类实际上是如何工作的呢?我知道这一点,它的主要工作是将操作排入特定线程 – 但它如何将这些操作“发送”到线程?线程如何“获得”这些行为?

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

解决方法

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

通常使用的模式是生产者 – 消费者.目标线程将围绕无限循环旋转,等待消息出现在阻塞队列中.该队列旨在阻塞,直到项目出现在队列中,从而防止目标线程不必要地消耗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);
  }
}

现在,在UI线程的情况下,它已经运行了一个消息循环,因此dispatcher类可以简单地将一条特殊消息发布到包含要执行的委托的消息队列中.在处理所有绘画,按钮点击等的过程中,UI特征消息也会被UI线程拾取,它将开始执行委托.

So how does the dispatcher class actually works? I’m aware of that,
it’s main job is to queue actions to a specific thread – but how does
it “send” those actions to the thread?

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

And how do the thread “get” these actions?

通过运行监视队列的无限循环.队列通常是一种称为阻塞队列的特殊类型,如果队列为空,则阻塞消耗线程.

My best guess is that there’s some kind of “thread queue” for each
thread,but then again I’ve got no idea.

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

原文地址:https://www.jb51.cc/csharp/99916.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐