如何实现异步安全的委托

时间:2017-06-28 14:07:40

标签: c# asynchronous async-await

我有Subscriber.cs接受操作,侦听RabbitMQ队列,并对来自该队列的任何消息执行所述操作:

public class Subscriber {

     public Subscriber(Action<T> consumeMessage)
            {
                _consumeMessage = consumeMessage;
            }

            ....

            void HandleMessage(T message) {
                    try
                    {
                          _consumeMessage(message);                          
                    }
                    catch (Exception e)
                    {                 
                        _logger.LogError("Some error message");
                    }
            }
    }

这很好,直到我(意外)提供了异步功能:

 var subscriber = new Subscriber<MyMessage>(
                consumeMessage: message =>
                {
                    messageHandler.HandleAsync(message);
                });

这会在火灾中执行操作并忘记&#39;时尚,它在工作时仍然有效,但在失败时无声地失败。

所以我尝试了这个:

   var subscriber = new Subscriber<MyMessage>(
                    async consumeMessage: message =>
                    {
                        await messageHandler.HandleAsync(message);
                    });

这当然看起来很漂亮,但不知何故导致异常发生在这个代码段中(而不是在Subscriber内)导致整个应用程序崩溃。

所以我尝试了这个:

   var subscriber = new Subscriber<MyMessage>(
                    consumeMessage: message =>
                    {
                        messageHandler.HandleAsync(message).GetAwaiter().GetResult();
                    });

这可以按预期工作,但可能导致死锁(如果我相信互联网)。

这也使我的Subscriber成为一个非常不友好且非常危险的组件,因为即使它们实际上不起作用,前两个例子都会编译。

我应该如何设计我的Subscriber组件,以便它可以安全地与异步代理一起使用?

0 个答案:

没有答案