如何实现异步观察者模式或事件

时间:2017-01-25 08:41:03

标签: c# .net

我正在寻找实现以下方法的方法:

A说:"哟,X发生了。再见"

其他人看到了并开始做一些工作。

换句话说,我想发动一个事件,让其他人以火灾和忘记的方式处理它。

所以我调查了观察者模式:https://msdn.microsoft.com/en-us/library/dd783449(v=vs.110).aspx。但是这个例子是同步的,如果观察者花了很长时间来完成他们的工作,那么notify方法会长时间阻塞。

我还研究了如何举办活动:https://msdn.microsoft.com/en-us/library/9aackb16(v=vs.110).aspx。此示例也是同步的,并且当处理程序需要很长时间来处理事件时,会长时间阻塞发送方。

我的问题是:

如何在C#中解雇并忘记事件/消息/代理?

1 个答案:

答案 0 :(得分:3)

可能你应该见Task Parallel Library (TPL) Dataflows。有一个名为ActionBlock<TInput>的数据流应该是一个很好的开端:

  

ActionBlock<TInput>类是调用委托的目标块   当它收到数据。将ActionBlock<TInput>对象视为一个   当数据可用时异步运行的委托。该   您提供给ActionBlock<TInput>对象的委托可以是   输入操作或输入System.Func<TInput, Task> [...]

因此,如何给Func<TInput, Task> ActionBlock<TInput>执行异步操作呢?我修改了TPL Dataflow MSDN article上的示例:

List<Func<int, Task>> observers = new List<Func<int, Task>>
{
      n => Console.WriteLine(n),
      n => Console.WriteLine(n * i),
      n => Console.WriteLine(n * n / i)
};

// Create an ActionBlock<int> object that prints values
// to the console.
var actionBlock = new ActionBlock<int>
(
    n => 
    {
         // Fire and forget call to all observers
         foreach(Func<int, Task> observer in observers)
         {
              // Don't await for its completion
              observer(n);
         }         
    }
);

// Post several messages to the block.
for (int i = 0; i < 3; i++)
{
   actionBlock.Post(i * 10);
}

// Set the block to the completed state
actionBlock.Complete();

// See how I commented out the following sentence.
// You don't wait actions to complete as you want the fire
// and forget behavior!
// actionBlock.Completion.Wait();

您可能还想查看BufferBlock<T>