private Task GetTaskForValueTaskSource(IValueTaskSource t) { Task completedTask; var status = t.GetStatus(Token); if (status == ValueTaskSourceStatus.Pending) { return(new ValueTaskSourceAsTask(t, Token).Task); } try { t.GetResult(Token); completedTask = CompletedTask; } catch (Exception exception1) { var exception = exception1; if (status != ValueTaskSourceStatus.Canceled) { var taskCompletionSource = new TaskCompletionSource <bool>(); taskCompletionSource.TrySetException(exception); completedTask = taskCompletionSource.Task; } else { completedTask = _task; } } return(completedTask); }
/// <summary>Creates a <see cref="Task{TResult}"/> to represent the <see cref="IValueTaskSource{TResult}"/>.</summary> /// <remarks> /// The <see cref="IValueTaskSource{TResult}"/> is passed in rather than reading and casting <see cref="_obj"/> /// so that the caller can pass in an object it's already validated. /// </remarks> private Task <TResult> GetTaskForValueTaskSource(IValueTaskSource <TResult> t) { ValueTaskSourceStatus status = t.GetStatus(_token); if (status != ValueTaskSourceStatus.Pending) { try { // Get the result of the operation and return a task for it. // If any exception occurred, propagate it return(AsyncTaskMethodBuilder <TResult> .GetTaskForResult(t.GetResult(_token))); // If status is Faulted or Canceled, GetResult should throw. But // we can't guarantee every implementation will do the "right thing". // If it doesn't throw, we just treat that as success and ignore // the status. } catch (Exception exc) { if (status == ValueTaskSourceStatus.Canceled) { if (exc is OperationCanceledException oce) { var task = new Task <TResult>(); task.TrySetCanceled(oce.CancellationToken, oce); return(task); } Task <TResult> canceledTask = s_canceledTask; if (canceledTask == null) { // Benign race condition to initialize cached task, as identity doesn't matter. s_canceledTask = Task.FromCanceled <TResult>(new CancellationToken(true)); } return(canceledTask); } else { return(Task.FromException <TResult>(exc)); } } } return(new ValueTaskSourceAsTask(t, _token)); }
/// <summary>Creates a <see cref="Task"/> to represent the <see cref="IValueTaskSource"/>.</summary> /// <remarks> /// The <see cref="IValueTaskSource"/> is passed in rather than reading and casting <see cref="_obj"/> /// so that the caller can pass in an object it's already validated. /// </remarks> private Task GetTaskForValueTaskSource(IValueTaskSource t) { ValueTaskSourceStatus status = t.GetStatus(_token); if (status != ValueTaskSourceStatus.Pending) { try { // Propagate any exceptions that may have occurred, then return // an already successfully completed task. t.GetResult(_token); return(Task.CompletedTask); // If status is Faulted or Canceled, GetResult should throw. But // we can't guarantee every implementation will do the "right thing". // If it doesn't throw, we just treat that as success and ignore // the status. } catch (Exception exc) { if (status == ValueTaskSourceStatus.Canceled) { if (exc is OperationCanceledException oce) { var task = new Task(); task.TrySetCanceled(oce.CancellationToken, oce); return(task); } // Benign race condition to initialize cached task, as identity doesn't matter. return(s_canceledTask ??= Task.FromCanceled(new CancellationToken(canceled: true))); } else { return(Task.FromException(exc)); } } } return(new ValueTaskSourceAsTask(t, _token)); }
private Task GetTaskForValueTaskSource(IValueTaskSource t) { ValueTaskSourceStatus status = t.GetStatus(_token); if (status == ValueTaskSourceStatus.Pending) { return(new ValueTaskSourceAsTask(t, _token).Task); } try { t.GetResult(_token); return(CompletedTask); } catch (Exception ex) { if (status == ValueTaskSourceStatus.Canceled) { return(s_canceledTask); } TaskCompletionSource <Boolean> completionSource = new TaskCompletionSource <Boolean>(); completionSource.TrySetException(ex); return(completionSource.Task); } }