【问题标题】:Writing a wrapper for an async method为异步方法编写包装器
【发布时间】:2013-03-08 19:03:58
【问题描述】:

我有一个 TransactionOperator 类,它公开了以下静态异步方法:

public static async Task<bool> ProcessTransactionAsync(Transaction transaction)
{
    var someTransactionOperator = ...; // get appropriate operator
    // some code here
    bool success = await someTransactionOperator.Process(transaction);
    // some more code
    return bool;
}

现在,我想在Transaction 类中提供一个包装器实例方法。我的问题是,这将是正确/推荐的写作方式?我倾向于 #2,因为它感觉不错,但我没有任何支持该选择的论据。

// Option 1
public bool ProcessAsync()
{
    return TransactionOperator.ProcessTransactionAsync(this).Result;
}

// Option 2
public Task<bool> ProcessAsync()
{
    return TransactionOperator.ProcessTransactionAsync(this);
}

// Option 3 (compiler warning because there's no 'await' operator)
public async Task<bool> ProcessAsync()
{
    return TransactionOperator.ProcessTransactionAsync(this).Result;
}

// Option 4
public async Task<bool> ProcessAsync()
{
    return await TransactionOperator.ProcessTransactionAsync(this);
}

【问题讨论】:

  • 考虑到第一种方法是非异步的,首先您需要决定是否需要/希望方法的异步特性传播到方法之外。
  • 选项 2 和 4 都有效。选项 3 普通不起作用,选项 1 非常危险(阅读会让你陷入僵局)。
  • @LasseV.Karlsen 我发布的第一个函数调用的实例方法TransactionOperator.Process(Transaction transaction) 等待来自网络的响应,所以我认为这是添加异步操作的好地方。跨度>
  • 选项 2 会让您在方法之外等待,我相信选项 4 应该是 public async bool ProcessAsync()

标签: c# .net asynchronous .net-4.5


【解决方案1】:

选项 2 是最好的选择。选项 4 在逻辑上是等效的,但开销更大。

选项 1 和 3 完全错误。它们都同步阻塞(即使选项 3 是async,它的行为也是同步的)。 Exposing synchronous wrappers for asynchronous methods is not recommended。除其他问题外,您可以cause deadlocks(正如我在博客中解释的那样)。

【讨论】:

  • 您能解释一下为什么选项 4 的开销更大吗?
  • @wensveen:它将async 状态机应用于该方法。
猜你喜欢
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多