What is the best way to wrap a task as a <TResult> task
I am writing some asynchronous helper methods, and I have an API to support both Task and Task<T> . To reuse the code, I would like the Task API to wrap the task as Task<T> and just call the Task<T> API.
One way to do this:
private static async Task<bool> Convert(this Task @this) { await @this.ConfigureAwait(false); return false; } However, I am wondering: is there a better way / built-in way to do this?
There is no existing Task method that does just that, no. Your method is fine, and most likely as simple as you can get.
Implementing the correct semantics of error propagation / cancellation using any other method is deceptively tough.
Updated , the following applies to exceptions and cancellations:
public static class TaskExt { public static Task<Empty> AsGeneric(this Task @this) { return @this.IsCompleted ? CompletedAsGeneric(@this) : @this.ContinueWith<Task<Empty>>(CompletedAsGeneric, TaskContinuationOptions.ExecuteSynchronously).Unwrap(); } static Task<Empty> CompletedAsGeneric(Task completedTask) { try { if (completedTask.Status != TaskStatus.RanToCompletion) // propagate exceptions completedTask.GetAwaiter().GetResult(); // return completed task return Task.FromResult(Empty.Value); } catch (OperationCanceledException ex) { // propagate cancellation if (completedTask.IsCanceled) // return cancelled task return new Task<Empty>(() => Empty.Value, ex.CancellationToken); throw; } } } public struct Empty { public static readonly Empty Value = default(Empty); } Using await seems a little redundant. There is no need for a destination machine, just use ContinueWith
private static Task<bool> Convert(this Task @this) { return @this.ContinueWith(p => { p.Wait(); return false;}); } Note. This will cause the AggregateException be completed, unfortunately