【问题标题】:Compose async methods with await? [duplicate]用等待编写异步方法? [复制]
【发布时间】: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&lt;Message&gt;。那么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


【解决方案1】:

在您引用的示例中,仅返回任务而不使用 await 就可以了(并且可以说更可取),但这确实需要小心。

当你在using 块内处理Tasks 时,你可能会遇到麻烦。它们可能有截然不同的行为:

public async Task<Something> AwaitTheTask()
{
    using (var someResource = GetAResource())
    {
        return await SomeAsyncThing(someResource);
    }
}

public Task<Something> DontAwaitTheTask()
{
    using (var someResource = GetAResource())
    {
        return SomeAsyncThing(someResource);
    }
}

在第一个示例中,using 块在等待的 Task 完成之前不会释放 someResource。在第二个示例中,someResource 将立即被释放,很可能会导致需要该资源的代码出现问题。

【讨论】:

  • 谢谢。对我来说,很明显你的两个样本的行为不同,因为在 await 之后发生了一些事情,如果我不等待,这将更早发生。
  • @ygoe 嗯,这对我来说并不是很明显,我不得不以艰难的方式学习这一点(^^);如果一个人不知道去寻找它们,很容易忘记这样的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
相关资源
最近更新 更多