public static ActivityScope Start( DiagnosticSource diagnosticSource, Activity activity, object?args = null) { var scope = new ActivityScope(diagnosticSource, activity, args); diagnosticSource.StartActivity(activity, args ?? Unit.Instance); return(scope); }
public static void RunAsyncPipeline <TCmdlet>( TCmdlet cmdlet, Func <TCmdlet, CancellationToken, Task> asyncMethod, string pipelineStage) where TCmdlet : Cmdlet, IAsyncCmdlet { using var diagnosticSource = new SwitchingDiagnosticSource( DiagnosticConstants.SourceName, DiagnosticConstants.TraceSwitchName); using var pipelineStageActivity = ActivityScope.Start( diagnosticSource, new Activity( DiagnosticConstants.AsyncPipelineStageActivity), new { StageName = pipelineStage }); using var context = AsyncCmdletContext.Start(cmdlet); var asyncTask = asyncMethod(cmdlet, context.GetCancellationToken()); if (asyncTask is null) { throw new InvalidOperationException(); } ExceptionDispatchInfo?exceptionDispatcher = null; try { asyncTask.ContinueWith( (t, state) => ((AsyncCmdletContext?)state) !.Close(), context, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current); foreach (var action in context.GetActions()) { using var pipelineStepActivity = ActivityScope.Start( diagnosticSource, new Activity( DiagnosticConstants.AsyncPipelineStepActivity)); action.Invoke(); } } finally { try { asyncTask.GetAwaiter().GetResult(); } catch (OperationCanceledException) { } catch (AggregateException ex) { var exceptions = ex.Flatten().InnerExceptions; var pse = exceptions.FirstOrDefault(e => e is PipelineStoppedException); if (pse != null) { exceptionDispatcher = ExceptionDispatchInfo.Capture(pse); } else if (exceptions.Any(e => !(e is OperationCanceledException))) { exceptionDispatcher = ExceptionDispatchInfo.Capture(ex); } } } exceptionDispatcher?.Throw(); }