事件与收益率

drh*_*ris 11 c# events multithreading yield

我有一个多线程应用程序,它为几个硬件工具生成线程.每个线程基本上都是一个无限循环(在应用程序的生命周期内),它会轮询硬件以获取新数据,并在每次收集新内容时激活一个事件(传递数据).有一个侦听器类可以合并所有这些乐器,执行一些计算,并通过此计算触发新事件.

但是,我想知道,由于只有一个侦听器,最好IEnumerable<>从这些乐器中公开一个方法,并使用a yield return来返回数据,而不是触发事件.

我想看看是否有人知道这两种方法的差异.特别是,我正在寻找最佳的可靠性,最佳的暂停/取消操作能力,最适合穿线,一般安全等.

另外,使用第二种方法是否仍然可以在IEnumerable单独的线程上运行循环?其中许多仪器都受CPU限制,因此确保每个仪器都在不同的线程上是至关重要的.

Jos*_*osh 7

这听起来像是Reactive Extensions的一个非常好的用例.它有一点学习曲线,但简而言之,IObservable是IEnumerable的双重性.IEnumerable要求您从中拉出,IObservable将其值推送到观察者.几乎任何时候你需要在你的枚举器中阻塞,这是一个好的迹象,你应该扭转模式并使用推模型.事件是一种方法,但IObservable具有更大的灵活性,因为它是可组合和线程感知的.

instrument.DataEvents
          .Where(x => x.SomeProperty == something)
          .BufferWithTime( TimeSpan.FromSeconds(1) )
          .Subscribe( x => DoSomethingWith(x) );
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,只要主题(工具)生成具有匹配SomeProperty的DataEvent并且将事件缓冲到1秒持续时间的批次中,就会调用DoSomethingWith(x).

你可以做更多的事情,例如合并其他主题产生的事件或将通知指向UI线程等.不幸的是,文档目前相当薄弱,但有一些关于Matthew Podwysocki博客的好信息.(虽然他的帖子几乎完全提到了JavaScript的Reactive Extensions,但它几乎都适用于.NET的Reactive Extensions.)