马歇尔手动线程

时间:2009-06-24 13:51:08

标签: c# multithreading

在WinForms中,你有Control.BeginInvoke(),这意味着你可以编组从后台线程到创建控件句柄的主UI线程的调用。

这很好,但是如何(在C#中)你会在两个“标准”线程之间做到这一点?

我编写了一个服务总线,它有一个处理器线程来消费消息。我想要一个计时器来触发,这会导致处理器线程做某事,而不是在计时器的线程中运行的代码。

当然我可以使用线程同步(Monitor / using() {...}),但想知道它是如何正常完成的。

2 个答案:

答案 0 :(得分:11)

不幸的是,答案很难在这里给出,因为它高度依赖于线程的性质。

线程之间的编组并不神奇。有一种潜在的机制可以做到。例如,在WinForms中,Control.Invoke样式函数通过消息传递工作。在UI线程中发布了一条消息,消息泵将最终提取此消息并将其转换为Marshal'd调用。

为了在标准线程之间编组调用,它必须具有一些能力,通过它可以检测到要发生的编组调用,然后进行该调用。这通常通过某种消息传递来完成。

恕我直言,最常用的方法是让你的线程实现,提供并安装SynchronizationContext。这是在线程之间定义Marshaling机制的更标准方法。

答案 1 :(得分:1)

Windows窗体运行message loop,这就是为什么你可以为所有类型的任务编组UI线程的原因 - 它反复查找队列中的消息,这些消息可以通过线程边界发送。

如果您想手动执行此操作,请创建自己的消息循环(对于一个或多个线程)或更简单,使用同步原语。对于这种情况,AutoResetEvent似乎是合适的。您只需要在正确的位置调用SetWaitOne方法,(当然要注意死锁)。