private void InvokeCallbacks() { var value = Interlocked.Exchange(ref _callback, _callbackCompletionSentinel); if (value != null) { var invokeAsync = (_flags & _flagRunContinuationsAsynchronously) != 0; if (value is CallbackCollection callbackList) { lock (callbackList) { callbackList.Invoke(invokeAsync); } } else if (invokeAsync) { CallbackUtility.InvokeCompletionCallbackAsync(this, value, SynchronizationContext.Current); } else { CallbackUtility.InvokeCompletionCallback(this, value); } } }
public void Invoke(bool invokeAsync) { if (_progressCallbacks != null) { foreach (var item in _progressCallbacks) { CallbackUtility.InvokeProgressCallback(_op, item.Callback, item.SyncContext); } } foreach (var item in this) { CallbackUtility.InvokeCompletionCallback(_op, item.Callback, item.SyncContext, invokeAsync); } }
/// <summary> /// Adds a completion callback to be executed after the operation has completed. If the operation is completed <paramref name="action"/> is invoked /// on the <paramref name="syncContext"/> specified. /// </summary> /// <remarks> /// The <paramref name="action"/> is invoked on a <see cref="SynchronizationContext"/> specified. Throwing an exception from the callback might cause unspecified behaviour. /// </remarks> /// <param name="action">The callback to be executed when the operation has completed. Can be one of <see cref="Action"/>, <see cref="Action{T}"/> /// (with <see cref="IAsyncOperation"/> argument type), <see cref="AsyncCallback"/>, <see cref="IAsyncContinuation"/> or <see cref="AsyncCompletedEventHandler"/>.</param> /// <param name="syncContext">If not <see langword="null"/> method attempts to marshal the continuation to the synchronization context. /// Otherwise the callback is invoked on a thread that initiated the operation completion. /// </param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="action"/> is <see langword="null"/>.</exception> /// <exception cref="ObjectDisposedException">Thrown is the operation has been disposed.</exception> /// <seealso cref="AddProgressCallback(object, SynchronizationContext)"/> /// <seealso cref="RemoveCallback(object)"/> public void AddCompletionCallback(object action, SynchronizationContext syncContext) { ThrowIfDisposed(); if (action == null) { throw new ArgumentNullException(nameof(action)); } if (!TryAddCallback(action, syncContext, true)) { var invokeAsync = (_flags & _flagRunContinuationsAsynchronously) != 0; CallbackUtility.InvokeCompletionCallback(this, action, syncContext, invokeAsync); } }
private void InvokeCompletionCallback(object continuation, SynchronizationContext syncContext) { if ((_flags & _flagRunContinuationsAsynchronously) != 0) { CallbackUtility.InvokeCompletionCallbackAsync(this, continuation, syncContext); } else if (syncContext == null || syncContext == SynchronizationContext.Current) { CallbackUtility.InvokeCompletionCallback(this, continuation); } else { syncContext.Post(args => CallbackUtility.InvokeCompletionCallback(this, args), continuation); } }
public void Invoke(bool invokeAsync) { if (_progressCallback1 != null) { CallbackUtility.InvokeProgressCallback(_op, _progressCallback1, _sharedContext); } if (_progressCallbacks != null) { foreach (var item in _progressCallbacks) { CallbackUtility.InvokeProgressCallback(_op, item, _sharedContext); } } if (_completionCallback1 != null) { CallbackUtility.InvokeCompletionCallback(_op, _completionCallback1, _sharedContext, invokeAsync); } if (_completionCallback2 != null) { CallbackUtility.InvokeCompletionCallback(_op, _completionCallback2, _sharedContext, invokeAsync); } if (_completionCallback3 != null) { CallbackUtility.InvokeCompletionCallback(_op, _completionCallback3, _sharedContext, invokeAsync); } if (_completionCallbacks != null) { foreach (var item in _completionCallbacks) { CallbackUtility.InvokeCompletionCallback(_op, item, _sharedContext, invokeAsync); } } }
private void InvokeCallbacks() { var value = Interlocked.Exchange(ref _callback, _callbackCompletionSentinel); if (value != null) { var invokeAsync = (_flags & _flagRunContinuationsAsynchronously) != 0; var continueOnDefaultContext = (_flags & _flagContinueOnDefaultContext) != 0; if (value is IAsyncCallbackCollection callbackList) { lock (callbackList) { callbackList.Invoke(invokeAsync); } } else { var syncContext = continueOnDefaultContext ? _defaultContext : SynchronizationContext.Current; CallbackUtility.InvokeCompletionCallback(this, value, syncContext, invokeAsync); } } }
private void InvokeInline(object callback) { Debug.Assert(callback != null); CallbackUtility.InvokeCompletionCallback(_op, callback); }