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);
        }