void System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment enlistment) { List <BatchManager <TItem> .BatchedObjectsAsyncResult> list; lock (this.batchManager.syncTransactionLock) { list = this.batchManager.transactionalBatchResults[this.transactionIdentifier].ToList <BatchManager <TItem> .BatchedObjectsAsyncResult>(); } TimeSpan maxValue = TimeSpan.MaxValue; foreach (BatchManager <TItem> .BatchedObjectsAsyncResult batchedObjectsAsyncResult in list) { if (batchedObjectsAsyncResult.RemainingTime >= maxValue) { continue; } maxValue = batchedObjectsAsyncResult.RemainingTime; } this.preparingEnlistment = enlistment; this.prepareCalled = true; try { BatchManager <TItem> .PerformFlushAsyncResult performFlushAsyncResult = new BatchManager <TItem> .PerformFlushAsyncResult(this.trackingContext, this.batchManager, list, this.transactionIdentifier, maxValue, BatchManager <TItem> .BatchNotification.onFlushCompleted, this); performFlushAsyncResult.StartOperation(); } catch (Exception exception1) { Exception exception = exception1; if (Fx.IsFatal(exception)) { throw; } MessagingClientEtwProvider.TraceClient(() => MessagingClientEtwProvider.Provider.EventWriteBatchManagerException(this.trackingContext.Activity, this.trackingContext.TrackingId, this.trackingContext.SystemTracker, string.Format(CultureInfo.InvariantCulture, "BatchManager<T>.BatchNotification.Prepare Rollback. Transaction ID: {0}", new object[] { this.transactionIdentifier }), exception.ToStringSlim())); TransactionResultManager.Instance.SetTransactionResult(this.transactionIdentifier, exception, this.trackingContext); try { this.preparingEnlistment.ForceRollback(exception); } catch (InvalidOperationException invalidOperationException1) { InvalidOperationException invalidOperationException = invalidOperationException1; MessagingClientEtwProvider.TraceClient(() => MessagingClientEtwProvider.Provider.EventWriteBatchManagerException(this.trackingContext.Activity, this.trackingContext.TrackingId, this.trackingContext.SystemTracker, "BatchManager<T>.BatchNotification.Prepare.ForceRollback", invalidOperationException.ToStringSlim())); } } }
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { TrackingContext instance = TrackingContext.GetInstance(Guid.NewGuid()); BatchManager <TItem> .PerformFlushAsyncResult performFlushAsyncResult = null; lock (this.syncLock) { if (this.flushTimer.Cancel()) { performFlushAsyncResult = this.BeginFlush(instance, timeout, callback, state); } } if (performFlushAsyncResult != null) { performFlushAsyncResult.StartOperation(); return(performFlushAsyncResult); } return(new CompletedAsyncResult(callback, state)); }
public IAsyncResult BeginBatchedOperation(TrackingContext trackingContext, IEnumerable <TItem> batchItems, TimeSpan timeout, AsyncCallback callback, object state) { base.ThrowIfDisposedOrNotOpen(); if (!batchItems.Any <TItem>()) { return(new CompletedAsyncResult(callback, state)); } Transaction current = Transaction.Current; int calculateBatchSize = this.CalculateBatchSize(batchItems); if (current != null) { string localIdentifier = current.TransactionInformation.LocalIdentifier; BatchManager <TItem> .BatchedObjectsAsyncResult batchedObjectsAsyncResult = new BatchManager <TItem> .BatchedObjectsAsyncResult(trackingContext, batchItems, calculateBatchSize, timeout, BatchManager <TItem> .transactionObjectCompleteCallback, state); lock (this.syncTransactionLock) { if (this.transactionalBatchResults.ContainsKey(localIdentifier)) { this.transactionalBatchResults[localIdentifier].Enqueue(batchedObjectsAsyncResult); } else { if (this.transactionCompletedEventHandler != null) { current.TransactionCompleted += this.transactionCompletedEventHandler; } current.EnlistVolatile(new BatchManager <TItem> .BatchNotification(trackingContext, this, localIdentifier), EnlistmentOptions.EnlistDuringPrepareRequired); Queue <BatchManager <TItem> .BatchedObjectsAsyncResult> batchedObjectsAsyncResults = new Queue <BatchManager <TItem> .BatchedObjectsAsyncResult>(); batchedObjectsAsyncResults.Enqueue(batchedObjectsAsyncResult); this.transactionalBatchResults.Add(localIdentifier, batchedObjectsAsyncResults); } } return(new CompletedAsyncResult(callback, state)); } if ((long)(this.batchOverheadSize + calculateBatchSize) >= this.maximumBatchSize) { return(this.BatchedBegin(trackingContext, batchItems, null, timeout, callback, state)); } BatchManager <TItem> .BatchedObjectsAsyncResult batchedObjectsAsyncResult1 = new BatchManager <TItem> .BatchedObjectsAsyncResult(trackingContext, batchItems, calculateBatchSize, timeout, callback, state); BatchManager <TItem> .PerformFlushAsyncResult performFlushAsyncResult = null; lock (this.syncLock) { this.batchedResults.Enqueue(batchedObjectsAsyncResult1); BatchManager <TItem> batchManager = this; batchManager.pendingBatchSize = batchManager.pendingBatchSize + calculateBatchSize; if ((long)this.pendingBatchSize >= this.flushThreshold) { if (!this.isTimerSet || this.flushTimer.Cancel()) { performFlushAsyncResult = this.BeginFlush(trackingContext, TimeSpan.MaxValue, BatchManager <TItem> .flushCompleteCallback, this); } } else if (!this.isTimerSet) { this.SetFlushTimer(false); } } if (performFlushAsyncResult != null) { performFlushAsyncResult.StartOperation(); if (performFlushAsyncResult.CompletedSynchronously) { this.EndFlush(performFlushAsyncResult); } } return(batchedObjectsAsyncResult1); }