コード例 #1
0
 public State(
     TaskCreationOptions fireTaskCreationOptions,
     TaskCreationOptions readyTaskCreationOptions)
 {
     FireSource  = TaskSource.New <Option <TEvent> >(fireTaskCreationOptions);
     ReadySource = TaskSource.New <Unit>(readyTaskCreationOptions);
 }
コード例 #2
0
        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);
コード例 #3
0
 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);
 }
コード例 #4
0
        // 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
        }
コード例 #5
0
 public void Increment()
 {
     lock (_lock) {
         if (DisposalState != DisposalState.Active)
         {
             throw Errors.AlreadyDisposedOrDisposing(DisposalState);
         }
         Count += 1;
         if (Count == 1)
         {
             _zeroSource = TaskSource.New <Unit>(_taskCreationOptions);
         }
     }
 }
コード例 #6
0
        // (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);
            }
        }
コード例 #7
0
 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);
     }
 }
コード例 #8
0
        public void Decrement()
        {
            TaskSource <Unit> zeroSource = default;

            lock (_lock) {
                Count -= 1;
                if (Count == 0)
                {
                    zeroSource  = _zeroSource;
                    _zeroSource = default;
                }
            }
            if (zeroSource.HasTask)
            {
                zeroSource.SetResult(default);
コード例 #9
0
        // 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);
        }
コード例 #10
0
        // 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 !);
コード例 #11
0
        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
        }
コード例 #12
0
 public void SetResult(Result <TOut> result, CancellationToken cancellationToken = default)
 => TaskSource.For(OutputTask).TrySetFromResult(result, cancellationToken);
コード例 #13
0
 public static TaskSource <T> New <T>(TaskCreationOptions taskCreationOptions)
 => new TaskSource <T>(TaskSource <T> .CreateTask2(null, taskCreationOptions));
コード例 #14
0
 public static TaskSource <T> New <T>(object?state, TaskCreationOptions taskCreationOptions)
 => new TaskSource <T>(TaskSource <T> .CreateTask2(state, taskCreationOptions));
コード例 #15
0
 public static TaskSource <T> New <T>(bool runContinuationsAsynchronously)
 => runContinuationsAsynchronously
         ? new TaskSource <T>(TaskSource <T> .CreateTask2(null, TaskCreationOptions.RunContinuationsAsynchronously))
         : new TaskSource <T>(TaskSource <T> .CreateTask0());
コード例 #16
0
 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);
 }