/// <summary> /// Create a Task based on Begin/End IAsyncResult pattern. /// </summary> /// <param name="transaction">The transaction (optional) to use. If not null a TransactionScope will be used when calling the begin Func.</param> /// <param name="begin"></param> /// <param name="end"></param> /// <param name="state"> /// This parameter helps reduce allocations by passing state to the Funcs. e.g.: /// await TaskHelpers.CreateTask( /// (c, s) => ((Transaction)s).BeginCommit(c, s), /// (a) => ((Transaction)a.AsyncState).EndCommit(a), /// transaction); /// </param> public static Task CreateTransactionalTask(Transaction transaction, Func <AsyncCallback, object, IAsyncResult> begin, Action <IAsyncResult> end, object state = null) { Task retval; TransactionScope scope = null; try { scope = Fx.CreateTransactionScope(transaction); retval = Task.Factory.FromAsync(begin, end, state); Fx.CompleteTransactionScope(ref scope); } catch (Exception ex) { if (Fx.IsFatal(ex)) { throw; } if (scope != null) { scope.Dispose(); } var completionSource = new TaskCompletionSource <object>(state); completionSource.SetException(ex); retval = completionSource.Task; } return(retval); }
public TransactionSignalScope(AsyncResult result, Transaction transaction) { Fx.Assert(transaction != null, "Null Transaction provided to AsyncResult.TransactionSignalScope."); this.parent = result; this.transactionScope = Fx.CreateTransactionScope(transaction); }