#pragma warning disable CA1000 // Do not declare static members on generic types /// <summary> /// Gets the task created by this task completion source. /// </summary> #pragma warning disable CA1707 // Remove the underscores from member name #pragma warning disable SA1300 // Element should begin with an uppercase letter #pragma warning disable IDE1006 // Naming Styles public static SystemTask get_Task(SystemTaskCompletionSource tcs) { var task = tcs.Task; CoyoteRuntime.Current?.RegisterKnownControlledTask(task); return(task); }
/// <summary> /// Wait for the next response /// </summary> /// <returns>The response from the server.</returns> private async System.Threading.Tasks.Task <Response> Receive(int timeout) { System.Threading.Tasks.Task task = await System.Threading.Tasks.Task.WhenAny( taskCompletion.Task, System.Threading.Tasks.Task.Delay(timeout)); if (task != taskCompletion.Task) { taskCompletion = new System.Threading.Tasks.TaskCompletionSource <Response>(); // Timeout reached throw new TimeoutException("Timeout when receiving message."); } if (task.Exception != null) { taskCompletion = new System.Threading.Tasks.TaskCompletionSource <Response>(); if (task.Exception.InnerException.InnerException != null) { throw task.Exception.InnerException.InnerException; } throw task.Exception; } var result = taskCompletion.Task.Result; // Since we can't re-use the task completion, create a new one for the next message taskCompletion = new System.Threading.Tasks.TaskCompletionSource <Response>(); return(result); }
private async ValueTask<int> AwaitTcsAsValueTask(TaskCompletionSource<int> tcs) => await new ValueTask<int>(tcs.Task).ConfigureAwait(false);
private static Task CopyResultToCompletionSourceImplContinuation <TTask, TResult>(TTask task, TaskCompletionSource <TResult> tcs, Func <TTask, TResult> resultThunk) where TTask : Task { return(task.ContinueWith(innerTask => { switch (innerTask.Status) { case TaskStatus.Canceled: case TaskStatus.Faulted: TaskHelpers.TrySetFromTask(tcs, innerTask); break; case TaskStatus.RanToCompletion: tcs.TrySetResult(resultThunk(task)); break; } }, TaskContinuationOptions.ExecuteSynchronously)); }
private static Task CopyResultToCompletionSourceImpl <TTask, TResult>(this TTask task, TaskCompletionSource <TResult> tcs, Func <TTask, TResult> resultThunk) where TTask : Task { // Stay on the same thread if we can if (task.IsCompleted) { switch (task.Status) { case TaskStatus.Canceled: case TaskStatus.Faulted: TaskHelpers.TrySetFromTask(tcs, task); break; case TaskStatus.RanToCompletion: tcs.TrySetResult(resultThunk(task)); break; } return(TaskHelpers.Completed()); } // Split into a continuation method so that we don't create a closure unnecessarily return(CopyResultToCompletionSourceImplContinuation(task, tcs, resultThunk)); }
internal static Task CopyResultToCompletionSource <TResult>(this Task <TResult> task, TaskCompletionSource <TResult> tcs) { return(task.CopyResultToCompletionSourceImpl(tcs, innerTask => innerTask.Result)); }
/// <summary> /// Attempts to transition the underlying task into the <see cref="SystemTasks.TaskStatus.Canceled"/> state /// and enables a cancellation token to be stored in the canceled task. /// </summary> public static bool TrySetCanceled(SystemTaskCompletionSource tcs, SystemCancellationToken cancellationToken) => tcs.TrySetCanceled(cancellationToken);
/// <summary> /// Attempts to transition the underlying task into the <see cref="SystemTasks.TaskStatus.Faulted"/> state /// and binds a collection of exception objects to it. /// </summary> public static bool TrySetException(SystemTaskCompletionSource tcs, IEnumerable <Exception> exceptions) => tcs.TrySetException(exceptions);
/// <summary> /// Attempts to transition the underlying task into the <see cref="SystemTasks.TaskStatus.RanToCompletion"/> state. /// </summary> public static bool TrySetResult(SystemTaskCompletionSource tcs) => tcs.TrySetResult();
/// <summary> /// Attempts to transition the underlying task into the <see cref="SystemTasks.TaskStatus.Faulted"/> state /// and binds it to a specified exception. /// </summary> public static bool TrySetException(SystemTaskCompletionSource tcs, Exception exception) => tcs.TrySetException(exception);
/// <summary> /// Transitions the underlying task into the <see cref="SystemTasks.TaskStatus.Canceled"/> state. /// </summary> public static void SetCanceled(SystemTaskCompletionSource tcs) => tcs.SetCanceled();
/// <summary> /// Transitions the underlying task into the <see cref="SystemTasks.TaskStatus.Faulted"/> state /// and binds it to a specified exception. /// </summary> public static void SetException(SystemTaskCompletionSource tcs, Exception exception) => tcs.SetException(exception);
#pragma warning restore CA1707 // Remove the underscores from member name #pragma warning restore SA1300 // Element should begin with an uppercase letter #pragma warning restore IDE1006 // Naming Styles /// <summary> /// Transitions the underlying task into the <see cref="SystemTasks.TaskStatus.RanToCompletion"/> state. /// </summary> public static void SetResult(SystemTaskCompletionSource tcs) => tcs.SetResult();
public SimpleWorkQueue(Func <IChannelHandlerContext, TWork, Task> workerAsync) { _workerAsync = workerAsync; _completionSource = new TaskCompletionSource(); _backlogQueue = new ConcurrentQueue <TWork>(); }
/// <summary> /// Attempts to transition the underlying task into the <see cref="SystemTasks.TaskStatus.Canceled"/> state. /// </summary> public static bool TrySetCanceled(SystemTaskCompletionSource tcs) => tcs.TrySetCanceled();
public static Task<TResult> FromResult<TResult> (TResult result) { var tcs = new TaskCompletionSource<TResult> (); tcs.SetResult (result); return tcs.Task; }
/// <summary> /// Asynchronously iterates through an enumerable of tasks. /// </summary> /// <param name="factory">The target factory.</param> /// <param name="source">The enumerable containing the tasks to be iterated through.</param> /// <param name="state">The asynchronous state for the returned Task.</param> /// <param name="cancellationToken">The cancellation token used to cancel the iteration.</param> /// <param name="creationOptions">Options that control the task's behavior.</param> /// <param name="scheduler">The scheduler to which tasks will be scheduled.</param> /// <returns>A Task that represents the complete asynchronous operation.</returns> public static Task Iterate(this TaskFactory factory, IEnumerable <object> source, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler) { // Validate/update parameters Contract.Requires(factory != null); Contract.Requires(source != null); Contract.Requires(scheduler != null); // Get an enumerator from the enumerable var enumerator = source.GetEnumerator(); if (enumerator == null) { throw new InvalidOperationException("Invalid enumerable - GetEnumerator returned null"); } // Create the task to be returned to the caller. And ensure // that when everything is done, the enumerator is cleaned up. var trs = new TaskCompletionSource <object>(state, creationOptions); trs.Task.ContinueWith(_ => enumerator.Dispose(), CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); // This will be called every time more work can be done. Action <Task> recursiveBody = null; recursiveBody = antecedent => { try { // If we should continue iterating and there's more to iterate // over, create a continuation to continue processing. We only // want to continue processing once the current Task (as yielded // from the enumerator) is complete. if (enumerator.MoveNext()) { var nextItem = enumerator.Current; // If we got a Task, continue from it to continue iterating if (nextItem is Task) { var nextTask = (Task)nextItem; nextTask.IgnoreExceptions(); // TODO: Is this a good idea? nextTask.ContinueWith(recursiveBody).IgnoreExceptions(); } //// If we got a scheduler, continue iterating under the new scheduler, //// enabling hopping between contexts. else if (nextItem is TaskScheduler) { Task.Factory.StartNew(() => recursiveBody(null), CancellationToken.None, TaskCreationOptions.None, (TaskScheduler)nextItem).IgnoreExceptions(); } //// Anything else is invalid else { trs.TrySetException(new InvalidOperationException("Task or TaskScheduler object expected in Iterate")); } } //// Otherwise, we're done! else { trs.TrySetResult(null); } } //// If MoveNext throws an exception, propagate that to the user, //// either as cancellation or as a fault catch (Exception exc) { var oce = exc as OperationCanceledException; if (oce != null && oce.CancellationToken == cancellationToken) { trs.TrySetCanceled(); } else { trs.TrySetException(exc); } } }; // Get things started by launching the first task factory.StartNew(() => recursiveBody(null), CancellationToken.None, TaskCreationOptions.None, scheduler).IgnoreExceptions(); // Return the representative task to the user return(trs.Task); }