我的代码可以根据需要精确运行。但是,我们的公司构建服务器拒绝任何具有编译器警告的签入。
为Action构造函数显示以下警告(正如预期),其中包含Action to Func转换,因为我没有使用await语句。
这种异步方法缺乏等待'运营商并将同步运行。考虑使用' await'运营商等待非阻塞API调用,或等待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)
{
//...
}
}
}
重写该代码的正确方法是什么,以便将Action正确转换为Func而不执行或创建新线程(即等待Task.Run())?
更新 - 建议的答案#1
我之前试过这个。它导致此单元测试永远不会返回。_operation =()=&gt;新任务(operation.Invoke);
_rollback =()=&gt;新任务(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);
}
更新 - 已接受的答案
private async Task ConvertToTask(Action action)
{
action.Invoke();
await Task.FromResult(true);
}
这里是更新的Action构造函数:
public TransactionOperation(Action operation, Action rollback)
{
_operation = () => ConvertToTask(operation);
_rollback = () => ConvertToTask(rollback);
Status = OperationStatus.NotStarted;
}
答案 0 :(得分:11)
您可以使用Task.FromResult(0)
:
_operation = async () => { operation.Invoke(); await Task.FromResult(0); };
答案 1 :(得分:2)
你的意思是这样的:
_operation = () => new Task(operation.Invoke);
_rollback = () => new Task(rollback.Invoke);
然后,函数将返回一个尚未启动的所需操作的任务。
我认为您需要将Invoke
方法更新为以下内容,以获取您正在寻找的行为:
Status = OperationStatus.InProcess;
await Task.Run(() =>
{
_operation().Start();
_operation().Wait();
});
Status = OperationStatus.Completed;