/// <inheritdoc/> public void Complete() { if (isCompleted) { throw new TransactionException("This transaction has already been completed."); } // Disabling synchronization context check: when we await for dispatcher task we always resume in a different SC so it makes it difficult to enforce this rule. //if (synchronizationContext != SynchronizationContext.Current) // throw new TransactionException("This transaction is being completed in a different synchronization context."); TryMergeOperations(); transactionStack.CompleteTransaction(this); // Don't keep reference to synchronization context after completion synchronizationContext = null; isCompleted = true; }
/// <inheritdoc/> public void Complete() { if (isCompleted) { throw new TransactionException("This transaction has already been completed."); } if (synchronizationContext != SynchronizationContext.Current) { throw new TransactionException("This transaction is being completed in a different synchronization context."); } TryMergeOperations(); transactionStack.CompleteTransaction(this); // Don't keep reference to synchronization context after completion synchronizationContext = null; isCompleted = true; }
/// <inheritdoc/> public void Complete() { if (isCompleted) { throw new TransactionException("This transaction has already been completed."); } if (synchronizationContext != SynchronizationContext.Current) { throw new TransactionException("This transaction is being completed in a different synchronization context."); } BeforeComplete?.Invoke(this, EventArgs.Empty); // Clear the reference since we're not supposed to exist as an ITransaction anymore, we're now disposed and turning to an IReadOnlyTransaction BeforeComplete = null; transactionStack.CompleteTransaction(this); // Don't keep reference to synchronization context after completion synchronizationContext = null; isCompleted = true; }
/// <inheritdoc/> public void Complete() { if (referenceCount == 0) { throw new TransactionException("This transaction has already been completed."); } // Transaction might be kept alive by others, only process it if last reference // Note: this KeepAlive() and Complete() are not thread-safe, no need to use interlocked if (referenceCount == 1) { // Disabling synchronization context check: when we await for dispatcher task we always resume in a different SC so it makes it difficult to enforce this rule. //if (synchronizationContext != SynchronizationContext.Current) // throw new TransactionException("This transaction is being completed in a different synchronization context."); TryMergeOperations(); transactionStack.CompleteTransaction(this); // Don't keep reference to synchronization context after completion synchronizationContext = null; } --referenceCount; }