public State( TaskCreationOptions fireTaskCreationOptions, TaskCreationOptions readyTaskCreationOptions) { FireSource = TaskSource.New <Option <TEvent> >(fireTaskCreationOptions); ReadySource = TaskSource.New <Unit>(readyTaskCreationOptions); }
protected virtual async Task DisposeAsync(bool disposing) { GC.SuppressFinalize(this); // The logic is a bit complicated b/c we want any DisposeAsync // call to complete only when the actual dispose completes, // not earlier. var oldDisposeCompleted = _disposeCompleted; if (oldDisposeCompleted != null) { await oldDisposeCompleted.ConfigureAwait(false); return; } // Double-check CAS to save on Task creation var disposeCompletedSource = TaskSource.New <Unit>(TaskCreationOptions.None); oldDisposeCompleted = Interlocked.CompareExchange( ref _disposeCompleted, disposeCompletedSource.Task, null); if (oldDisposeCompleted != null) { await oldDisposeCompleted.ConfigureAwait(false); return; } try { await DisposeInternal(disposing).ConfigureAwait(false); } catch { // DisposeAsync should never throw } finally { disposeCompletedSource.TrySetResult(default);
public bool TryCancel(CancellationToken cancellationToken = default) { if (CancellationToken.IsCancellationRequested) { TaskSource.For(OutputTask).TrySetCanceled(CancellationToken); } else if (cancellationToken.IsCancellationRequested) { TaskSource.For(OutputTask).TrySetCanceled(cancellationToken); } return(OutputTask.IsCanceled); }
// ToTask (untyped) public static Disposable <Task, CancellationTokenRegistration> ToTask( this CancellationToken token, TaskCreationOptions taskCreationOptions = default) { var ts = TaskSource.New <Unit>(taskCreationOptions); var r = token.Register(arg => TaskSource.For((Task <Unit>)arg !).SetCanceled(), ts.Task); #if NETSTANDARD return(Disposable.New((Task)ts.Task, r, (_, r1) => r1.Dispose())); #else return(Disposable.New((Task)ts.Task, r, (_, r1) => r1.Unregister())); #endif }
public void Increment() { lock (_lock) { if (DisposalState != DisposalState.Active) { throw Errors.AlreadyDisposedOrDisposing(DisposalState); } Count += 1; if (Count == 1) { _zeroSource = TaskSource.New <Unit>(_taskCreationOptions); } } }
// (Try)SetFromTask public static void SetFromTask <T>(this TaskSource <T> target, Task <T> source) { if (source.IsCanceled) { target.SetCanceled(); } else if (source.Exception != null) { target.SetException(source.Exception); } else { target.SetResult(source.Result); } }
public static void TrySetFromResult <T>(this TaskSource <T> target, Result <T> source, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { target.TrySetCanceled(); } else if (source.Error != null) { target.TrySetException(source.Error); } else { target.TrySetResult(source.Value); } }
public void Decrement() { TaskSource <Unit> zeroSource = default; lock (_lock) { Count -= 1; if (Count == 0) { zeroSource = _zeroSource; _zeroSource = default; } } if (zeroSource.HasTask) { zeroSource.SetResult(default);
// WithCancellation public static Task <T> WithCancellation <T>(this TaskSource <T> target, CancellationToken cancellationToken) { var task = target.Task; if (task.IsCompleted) { return(task); } if (cancellationToken != default) { cancellationToken.Register(arg => { var target1 = (TaskSource <T>)arg !; target1.TrySetCanceled(); }, target); } return(task); }
// ToTaskSource // Note that this method won't release the token unless it's cancelled! public static TaskSource <T> ToTaskSource <T>(this CancellationToken token, bool throwIfCancelled, TaskCreationOptions taskCreationOptions = default) { var ts = TaskSource.New <T>(taskCreationOptions); if (throwIfCancelled) { token.Register(arg => { var ts1 = (TaskSource <T>)arg; ts1.SetCanceled(); }, ts); } else { token.Register(arg => { var tcs1 = (TaskSource <T>)arg; tcs1.SetResult(default !);
public static Disposable <Task, CancellationTokenRegistration> ToTask( this CancellationToken token, Exception exceptionWhenCancelled, TaskCreationOptions taskCreationOptions = default) { // ReSharper disable once HeapView.PossibleBoxingAllocation var ts = TaskSource.New <Unit>(exceptionWhenCancelled, taskCreationOptions); var r = token.Register(arg => { var ts1 = TaskSource.For((Task <Unit>)arg !); ts1.SetException((Exception)ts1.Task.AsyncState !); }, ts.Task); #if NETSTANDARD return(Disposable.New((Task)ts.Task, r, (_, r1) => r1.Dispose())); #else return(Disposable.New((Task)ts.Task, r, (_, r1) => r1.Unregister())); #endif }
public void SetResult(Result <TOut> result, CancellationToken cancellationToken = default) => TaskSource.For(OutputTask).TrySetFromResult(result, cancellationToken);
public static TaskSource <T> New <T>(TaskCreationOptions taskCreationOptions) => new TaskSource <T>(TaskSource <T> .CreateTask2(null, taskCreationOptions));
public static TaskSource <T> New <T>(object?state, TaskCreationOptions taskCreationOptions) => new TaskSource <T>(TaskSource <T> .CreateTask2(state, taskCreationOptions));
public static TaskSource <T> New <T>(bool runContinuationsAsynchronously) => runContinuationsAsynchronously ? new TaskSource <T>(TaskSource <T> .CreateTask2(null, TaskCreationOptions.RunContinuationsAsynchronously)) : new TaskSource <T>(TaskSource <T> .CreateTask0());
public State(State previousState, bool complete) { IsCompleted = previousState.IsCompleted | complete; FireSource = TaskSource.New <Option <TEvent> >(previousState.FireSource.Task.CreationOptions); ReadySource = TaskSource.New <Unit>(previousState.ReadySource.Task.CreationOptions); }