public Task <bool> WaitToReadAsync(CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(Task.FromCanceled <bool>(cancellationToken));
                }

                switch (_task.Status)
                {
                case TaskStatus.Faulted:
                case TaskStatus.Canceled:
                    return(s_falseTask);

                case TaskStatus.RanToCompletion:
                    return(_completion.Task.IsCompleted ? s_falseTask : s_trueTask);

                default:
                    return(_task.ContinueWith((_, s) =>
                    {
                        TaskChannel <T> thisRef = (TaskChannel <T>)s;
                        return
                        thisRef._task.Status == TaskStatus.RanToCompletion &&
                        !thisRef._completion.Task.IsCompleted;
                    }, this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default));
                }
            }
            public ValueTask <T> ReadAsync(CancellationToken cancellationToken)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(new ValueTask <T>(Task.FromCanceled <T>(cancellationToken)));
                }

                switch (_task.Status)
                {
                case TaskStatus.Faulted:
                    return(new ValueTask <T>(_task));

                case TaskStatus.Canceled:
                    return(new ValueTask <T>(Task.FromException <T>(CreateInvalidCompletionException())));

                case TaskStatus.RanToCompletion:
                    return(new ValueTask <T>(TransitionRead() ?
                                             _task :
                                             Task.FromException <T>(CreateInvalidCompletionException())));

                default:
                    return(new ValueTask <T>(_task.ContinueWith((_, s) =>
                    {
                        TaskChannel <T> thisRef = (TaskChannel <T>)s;
                        return thisRef.ReadAsync(CancellationToken.None).GetAwaiter().GetResult();
                    }, this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)));
                }
            }