I have a code that works exactly as desired. However, our corporate build server rejects any registration that has a compiler warning.
The following warning (as expected) displayed for an Action constructor with Action to Func transformations, since I am not using a wait statement.
In this asynchronous method, there are no โwaitโ statements and will be executed synchronously. Think about how to use the โwaitโ operator to wait for non-blocking API calls or โwait for Task.Run (...)โ to do the work of binding to the processor in the background thread.
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) { //... } } }
What is the correct way to rewrite this code so that the action is correctly converted to Func without executing or creating a new thread (i.e. wait for Task.Run ())?
Update - Proposed Answer No. 1
_operation = () => new task (operation .Invoke);
_rollback = () => new task (rollback.Invoke);
I have tried this before. This causes this unit test to never return.
[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); }
Refresh - accepted answer
private async Task ConvertToTask(Action action) { action.Invoke(); await Task.FromResult(true); }
Here's the updated Action constructor:
public TransactionOperation(Action operation, Action rollback) { _operation = () => ConvertToTask(operation); _rollback = () => ConvertToTask(rollback); Status = OperationStatus.NotStarted; }