繁体   English   中英

在一个线程中引发事件以调用第二个线程中的方法

[英]Raise event in one thread to invoke methods in a second thread

我正在开发一个程序,它可以响应来自互联网套接字的事件,也可能来自定时器。 使用两个线程似乎很自然:

  • 一个主要计划
  • 第二个侦听套接字,解析输入并引发适当的事件。

其他要求:

  1. 应用程序不应该依赖UI线程(它可以作为控制台应用程序运行)。
  2. 主程序应该同步处理消息,即按照它们到达的顺序。
  3. 主线程不能阻塞等待定时器(我想这意味着我必须在不同的线程上运行定时器)。

现在有些问题:-):

  1. 我猜测需求#1意味着我没有内置消息泵,所以我不能使用套接字监听器/定时器线程中的Invoke() 它是否正确?
  2. 如何在一个线程(例如监听器)上安全地引发事件,并让订户在另一个线程(主线程)上同步运行?
  3. 在后续处理程序完成之前,很可能会引发新事件。 在这种情况下会发生什么? CLR会在某个地方对事件进行缓冲,还是会被忽略?

最后但并非最不重要:我想我的目标是消息生产者/消费者范例的并行,但我想使用事件而不是消息。 你认为有更好的方法吗?

谢谢,

波阿斯

编辑

我想首先解释一下使用事件的动机。 该应用程序是一个自动交易引擎,必须响应市场中发生的事件(例如股票价格的变化)。 发生这种情况时,主线程上可能有多个订阅者应该被调用,这是使用事件的经典场景。

我想我总是可以使用Producer / Consumer和一些消息队列,并让消费者在主线程上引发事件,但我认为可能有更直接的方式。

我认为使用消息将是最简单的方法。 如果你使用的是C#4,这要归功于BlockingCollection <>

所以有一个共享的BlockingCollection,其中Message是你的消息类。

然后在你的工作线程中你这样做

var msgEnum = blockingCollection.GetConsumingEnumerable();

//Per thread
foreach( Message message in msgEnum )
{
   //Process messages here
}

这就对了。

GetConsumingEnumerable()将阻塞,直到有消息要处理。 然后它将从队列中删除消息,您的循环将处理它。

这有什么好处,你可以添加更多的线程,每个线程都有foreach循环。

完成后调用blockingCollection.CompletedAdding();

BTW队列处理并发并将队列消息同时排队等。

希望这可以帮助

安德烈

您可以在线程之间实现共享队列。 每当引发事件时,您都可以将其推入队列中。 主线程是一个无限循环,它检查新事件,从队列中删除它们,处理事件,当没有更多事件时,它会休眠一段时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM