为异步方法编写包装器

本文关键字:包装 异步方法 | 更新日期: 2023-09-27 18:03:14

我有一个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在逻辑上是等价的,但是开销更大。

选项1和3完全是错误的。它们都同步阻塞(即使选项3是async,它的行为也是同步的)。不建议为异步方法公开同步包装器。在其他问题中,您可能会导致死锁(正如我在我的博客中所解释的)。