private Task WrapTask(Task task, DiagTaskTracer diagTracer) { if (task is null) { throw new TaskCreatorReturnedNullException(); } // Handle exceptions that are thrown in the synchronous part. if (task.IsFaulted) { diagTracer?.LogCompletedSynchronouslyAsFaulted(task.Exception); this.exceptionHandler.HandleAll(task.Exception); return(task); } if (task.IsCanceled) { diagTracer?.LogCompletedSynchronouslyAsCanceled(); // Log a exception to avoid silent failures. this.exceptionHandler.Handle(new ComponentTaskCanceledException()); return(task); } // Fast path if the task completes synchronously. if (task.IsCompleted) { diagTracer?.LogCompletedSynchronouslyAsSuccess(default);
/// <inheritdoc cref="ITaskRunner.StartTask(Func{CancellationToken, Task})"/> /// <param name="logger">Optional logger to output diagnostic messages to.</param> public Task StartTask( Func <CancellationToken, Task> taskCreator, IDiagnosticLogger logger) { if (taskCreator is null) { throw new ArgumentNullException(nameof(taskCreator)); } if (this.isDisposed) { throw new ObjectDisposedException(nameof(LocalTaskRunner)); } // Activate our context and wrap the task. using (var contextScope = ContextScope.WithContext(this.context)) { var diagTracer = logger is null ? null : DiagTaskTracer.Create(logger, taskCreator); diagTracer?.LogInvoked(); return(this.WrapTask(taskCreator.Invoke(this.cancelSource.Token), diagTracer)); } }