public static Task InvokeAsync([NotNull] this IDispatcherService service, [NotNull] Func<Task> action) { Guard.NotNull(service, nameof(service)); Guard.NotNull(action, nameof(action)); var tcs = new TaskCompletionSource(); service.InvokeAsync(new Action(() => { action().ContinueWith(t => { if (t.Exception != null) { tcs.TrySetException(t.Exception); return; } if (t.IsCanceled) { tcs.TrySetCanceled(); } tcs.TrySetResult(); }); })); return tcs.Task; }
/// <summary> /// Returns a <see cref="Task"/> that is canceled when this <see cref="CancellationToken"/> is canceled. This method will leak resources if the cancellation token is long-lived; use <see cref="ToCancellationTokenTaskSource"/> for a similar approach with proper resource management. /// </summary> /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor.</param> /// <returns>A <see cref="Task"/> that is canceled when this <see cref="CancellationToken"/> is canceled.</returns> public static Task AsTask(this CancellationToken cancellationToken) { if (!cancellationToken.CanBeCanceled) return TaskConstants.Never; if (cancellationToken.IsCancellationRequested) return TaskConstants.Canceled; var tcs = new TaskCompletionSource(); cancellationToken.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: false); return tcs.Task; }
public static async Task ConfigureTopologyAsync(this Link @this, Func<ILinkTopologyConfig, Task> configure, CancellationToken cancellationToken) { var completion = new TaskCompletionSource(); if (cancellationToken.IsCancellationRequested) { completion.TrySetCanceled(); await completion.Task; return; } using (@this.CreateTopologyConfigurator(configure, () => { completion.TrySetResultWithBackgroundContinuations(); return Task.FromResult((object) null); }, ex => { completion.TrySetExceptionWithBackgroundContinuations(ex); return Task.FromResult((object) null); })) { IDisposable registration = null; try { registration = cancellationToken.Register(() => { completion.TrySetCanceledWithBackgroundContinuations(); }); } catch (ObjectDisposedException) { // Cancellation source already disposed } if (cancellationToken.IsCancellationRequested) { completion.TrySetCanceledWithBackgroundContinuations(); } try { await completion.Task .ConfigureAwait(false); } finally { registration?.Dispose(); } } }
/// <summary> /// Creates a task for the specified cancellation token, registering with the token if necessary. /// </summary> /// <param name="cancellationToken">The cancellation token to observe.</param> public CancellationTokenTaskSource(CancellationToken cancellationToken) { if (!cancellationToken.CanBeCanceled) { Task = TaskConstants.Never; return; } if (cancellationToken.IsCancellationRequested) { Task = TaskConstants.Canceled; return; } var tcs = new TaskCompletionSource(); _registration = cancellationToken.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: false); Task = tcs.Task; }
private static AsyncCallback Callback(Action<IAsyncResult> endMethod, TaskCompletionSource<object> tcs) { return asyncResult => { try { endMethod(asyncResult); tcs.TrySetResult(null); } catch (OperationCanceledException) { tcs.TrySetCanceled(); } catch (Exception ex) { tcs.TrySetException(ex); } }; }
private static Task<string> DumpWebPageAsync(WebClient client, Uri uri) { //si utilizza TaskCompletionSource che gestisce un task figlio var tcs = new TaskCompletionSource<string>(); DownloadStringCompletedEventHandler handler = null; handler = (sender, args) => { client.DownloadStringCompleted -= handler; if (args.Cancelled) tcs.TrySetCanceled(); else if (args.Error != null) tcs.TrySetException(args.Error); else tcs.TrySetResult(args.Result); }; client.DownloadStringCompleted += handler; client.DownloadStringAsync(uri); return tcs.Task; }
public void TrySetCanceled_CancelsTask() { var tcs = new TaskCompletionSource(); tcs.TrySetCanceled(); Assert.IsTrue(tcs.Task.IsCanceled); }