/// <summary> /// Awaits a task execution on the specified scheduler, providing the result. /// </summary> /// <returns>A task that will provide the result of the execution.</returns> public static Task <T> Run <T>(this IScheduler source, Func <T> func, CancellationToken cancellationToken) { var completion = new FastTaskCompletionSource <T>(); var disposable = new SingleAssignmentDisposable(); var ctr = default(CancellationTokenRegistration); if (cancellationToken.CanBeCanceled) { ctr = cancellationToken.Register(() => { completion.TrySetCanceled(); disposable.Dispose(); }); } disposable.Disposable = source.Schedule( () => { if (disposable.IsDisposed) { return; // CT canceled } try { var result = func(); completion.TrySetResult(result); } catch (Exception e) { completion.TrySetException(e); } finally { ctr.Dispose(); } } ); return(completion.Task); }
/// <summary> /// Awaits a task on the specified scheduler, without providing a result. /// </summary> /// <returns>A task that will complete when the work has completed.</returns> public static Task Run(this IScheduler source, Action action, CancellationToken ct) { var completion = new FastTaskCompletionSource <Unit>(); var disposable = new SingleAssignmentDisposable(); var ctr = default(CancellationTokenRegistration); if (ct.CanBeCanceled) { ctr = ct.Register(() => { completion.TrySetCanceled(); disposable.Dispose(); }); } disposable.Disposable = source.Schedule( () => { if (disposable.IsDisposed) { return; // CT canceled } try { action(); completion.TrySetResult(Unit.Default); } catch (Exception e) { completion.TrySetException(e); } finally { ctr.Dispose(); } } ); return(completion.Task); }
/// <summary> /// Awaits a task execution on the specified scheduler, providing the result. /// </summary> /// <returns>A task that will provide the result of the execution.</returns> public static Task <T> Run <T>(this IScheduler source, Func <CancellationToken, Task <T> > taskBuilder, CancellationToken cancellationToken) { var completion = new FastTaskCompletionSource <T>(); var disposable = new SingleAssignmentDisposable(); var ctr = default(CancellationTokenRegistration); if (cancellationToken.CanBeCanceled) { ctr = cancellationToken.Register(() => { completion.TrySetCanceled(); disposable.Dispose(); }); } disposable.Disposable = source.ScheduleTask( async(ct, _) => { try { var result = await taskBuilder(ct); completion.TrySetResult(result); } catch (Exception e) { completion.TrySetException(e); } finally { ctr.Dispose(); } } ); return(completion.Task); }