【发布时间】:2018-06-23 13:18:29
【问题描述】:
当将方法调用传递给另一个异步方法时,调用方方法是否也应该是异步的并使用等待,还是应该简单地传递从被调用方接收到的任务?如果调用方法多做一点准备呢?
public Task<Message> Unsubscribe(int subscriptionId, CancellationToken cancellationToken)
{
var data = new MessageData
{
["subscriptionId"] = subscriptionId
};
return SendAsync(OpCode.Unsubscribe, data, cancellationToken);
}
public Task<Message> Unsubscribe(int subscriptionId) =>
Unsubscribe(subscriptionId, CancellationToken.None);
SendAsync 是异步的并返回 Task<Message>。那么Unsubscribe 的第一个重载应该像上面还是那样:
public async Task<Message> Unsubscribe(int subscriptionId, CancellationToken cancellationToken)
{
var data = new MessageData
{
["subscriptionId"] = subscriptionId
};
return await SendAsync(OpCode.Unsubscribe, data, cancellationToken);
}
另一种选择是Unsubscribe 的第二个重载。它可能像上面或那样:
public async Task<Message> Unsubscribe(int subscriptionId) =>
await Unsubscribe(subscriptionId, CancellationToken.None);
我猜想更多的异步和等待会增加编译器引入的复杂性(我在堆栈跟踪中看到了它!)并且可能会降低性能和内存消耗。但至少它应该提供一致的异常传播。
【问题讨论】:
-
还有其他细微的差别。特别是,你应该使用
ConfigureAwait(false);否则,您的第二个版本可能会出现死锁。 -
“SendAsync 是异步的” 是 SendAsync() 的内部事务。对于调用者来说,它是可等待的。 Unsubscribe() 的两个版本也是如此。
-
有更多类似的问题,但我选择的欺骗提供了更好的解释和链接。
标签: c# .net asynchronous async-await