如何在不运行任务的情况下将Action转换为Func <Task>?

Sil*_*gel 9 c# asynchronous async-await

我的代码可以按照需要精确工作.但是,我们的公司构建服务器拒绝任何具有编译器警告的签入.

对于具有Action to Func转换的Action构造函数,显示以下警告(正如预期),因为我没有使用await语句.

这种异步方法缺少"等待"运算符并将同步运行.考虑使用'await'运算符等待非阻塞API调用,或'await Task.Run(...)'在后台线程上执行CPU绑定工作.

public class TransactionOperation
{
    private readonly Func<Task> _operation;
    private readonly Func<Task> _rollback;

    public OperationStatus Status { get; private set; }

    public TransactionOperation(Func<Task> operation, Func<Task> rollback)
    {
        _operation = operation;
        _rollback = rollback;
        Status = OperationStatus.NotStarted;
    }

    public TransactionOperation(Action operation, Action rollback)
    {
        _operation = async () => operation.Invoke();
        _rollback = async () => rollback.Invoke();
        Status = OperationStatus.NotStarted;
    }

    public async Task Invoke()
    {
        try
        {
            Status = OperationStatus.InProcess;
            await _operation.Invoke();
            Status = OperationStatus.Completed;
        }
        catch (Exception ex)
        {
            //...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

重写该代码的正确方法是什么,以便将Action正确转换为Func而不执行或创建新线程(即等待Task.Run())?


更新 - 建议的答案#1

_operation =()=> new Task(operation.Invoke);

_rollback =()=> new Task(rollback.Invoke);

我之前试过这个.它导致此单元测试永不返回.

[TestMethod, TestCategory("Unit Test")]
public async Task Transaction_MultiStepTransactionExceptionOnFourthAction_CorrectActionsRolledBack()
{
    var operation = new TransactionOperation(PerformAction, () => RollbackOperation(1));
    var operation2 = new TransactionOperation(PerformAction, () => RollbackOperation(2));
    var operation3 = new TransactionOperation(PerformAction, () => RollbackOperation(3));
    var operation4 = new TransactionOperation(ExceptionAction, () => RollbackOperation(4));
    var operation5 = new TransactionOperation(PerformAction, () => RollbackOperation(5));
    var transaction = new Transaction(new[] { operation, operation2, operation3, operation4, operation5 });

    await IgnoreExceptions(transaction.ExecuteAsync);

    AssertActionsPerformedThrough(4);
    AssertActionsRolledBackThrough(4);
}
Run Code Online (Sandbox Code Playgroud)

更新 - 已接受的答案

private async Task ConvertToTask(Action action)
{
    action.Invoke();
    await Task.FromResult(true);
}
Run Code Online (Sandbox Code Playgroud)

这是更新的Action构造函数:

public TransactionOperation(Action operation, Action rollback)
{
    _operation = () => ConvertToTask(operation);
    _rollback = () => ConvertToTask(rollback);
    Status = OperationStatus.NotStarted;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 12

你可以使用Task.FromResult(0):

_operation = async () => { operation.Invoke(); await Task.FromResult(0); };
Run Code Online (Sandbox Code Playgroud)

  • @ShaulBehr:不.答案写完时它根本不存在. (6认同)
  • 有什么理由不使用“await Task.CompletedTask”而不是“Task.FromResult(0)”? (3认同)