Azure ServiceBus TopicClient SendAsync实现在自己的包装器中

时间:2017-02-08 16:52:14

标签: async-await idisposable azureservicebus

Azure ServiceBus TopicClient的SendAsync方法的正确实现是什么?

在第二个实现中,BrokeredMessage是否会在SendAsync发生之前被处理掉?

    public async Task SendAsync<TMessage>(TMessage message, IDictionary<string, object> properties = null)
    {
        using (var bm = MessagingHelper.CreateBrokeredMessage(message, properties))
        {
            await this._topicClient.Value.SendAsync(bm);
        }
    }


    public Task SendAsync<TMessage>(TMessage message, IDictionary<string, object> properties = null)
    {
        using (var bm = MessagingHelper.CreateBrokeredMessage(message, properties))
        {
            return this._topicClient.Value.SendAsync(bm);
        }
    }

我想从await / async模式获得最多。

1 个答案:

答案 0 :(得分:0)

回答你的问题:第二种方法可能会导致处置对象出现问题,你必须等到SendAsync执行结束才能释放资源。

详细解释。

如果你打电话给await,方法的执行将在同一时刻停止,并且不会继续,直到没有返回等待的方法。 Brokered消息将存储在本地隐藏变量中,不会被处理。

如果你不调用await,执行将继续,并且在实际使用之前将释放所有代码消息资源(因为using正在调用对象上的Dispose结束)或在消费过程中。这定义将导致SendAsync内的异常。此时,SendAsync 的执行实际上已经开始

await做什么是“暂停”任何当前线程并等待完成任务及其结果。这就是你真正需要的。 async-await的目的是允许与其他任务同时执行某些任务,它提供了在真正需要时等待并发操作的结果的能力,并且在没有它的情况下无法进一步执行。

如果顶层的每个方法都是异步方法,那么第一种方法是好的。我的意思是,如果您的SendAsync的调用者是异步任务,并且该调用者的调用者等等,则调用顶级调用方法。

另外,考虑可能引发的异常,列出here。如您所见,存在所谓的瞬态错误。这是重试可能修复的一种错误。在您的代码中,没有此类异常处理。可以找到重试模式的示例here,但是提到的关于异常的文章可以提出更好的解决方案,这是另一个问题的主题。我还要添加一些日志系统,至少要注意任何非瞬态异常。