private async Task RunDelegateWithTransaction(TransactionInfo ambientTransactionInfo, Func <Task <bool> > transactionDelegate) { TransactionInfo transactionInfo; if (ambientTransactionInfo is null) { // TODO: this should be a configurable parameter var transactionTimeout = Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(10); // Start transaction transactionInfo = await _transactionAgent.StartTransaction(readOnly : false, transactionTimeout); } else { // Fork ambient transaction transactionInfo = ambientTransactionInfo.Fork(); } // Set transaction context TransactionContext.SetTransactionInfo(transactionInfo); try { // Run delegate transactionInfo.TryToCommit = await transactionDelegate(); } catch (Exception exception) { // Record exception with transaction transactionInfo.RecordException(exception, _serializer); } // Gather pending actions into transaction transactionInfo.ReconcilePending(); if (ambientTransactionInfo is null) { // Finalize transaction since there is no ambient transaction to join await FinalizeTransaction(transactionInfo); } else { // Join transaction with ambient transaction ambientTransactionInfo.Join(transactionInfo); } }