public static bool TryGetContext <TCmdlet>( TCmdlet cmdlet, [MaybeNullWhen(false)] out AsyncCmdletContext context) where TCmdlet : Cmdlet, IAsyncCmdlet { Requires.NotNull(cmdlet, nameof(cmdlet)); context = null !; if (!_contexts.TryGetValue(cmdlet, out var ctx)) { return(false); } if (ctx._disposed) { return(false); } context = ctx; return(true); }
public static AsyncCmdletContext Start <TCmdlet>( TCmdlet cmdlet) where TCmdlet : Cmdlet, IAsyncCmdlet { Requires.NotNull(cmdlet, nameof(cmdlet)); var context = new AsyncCmdletContext(cmdlet); return(context); }
public static void CancelAsyncOperations <TCmdlet>( this TCmdlet cmdlet) where TCmdlet : Cmdlet, IAsyncCmdlet { Requires.NotNull(cmdlet, nameof(cmdlet)); if (AsyncCmdletContext.TryGetContext(cmdlet, out var context)) { context.CancelAsyncOperations(); } }
internal static Task <TResult> QueueAction <TCmdlet, TArgument, TResult>( this TCmdlet cmdlet, Func <TCmdlet, TArgument, AsyncCmdletContext, TResult> action, TArgument argument, bool runSynchronouslyIfOnTheMainThread, CancellationToken cancellationToken) where TCmdlet : Cmdlet, IAsyncCmdlet { Requires.NotNull(cmdlet, nameof(cmdlet)); Requires.NotNull(action, nameof(action)); var context = AsyncCmdletContext.GetContext(cmdlet); var task = context.QueueAction( cmdlet, action, argument, runSynchronouslyIfOnTheMainThread, cancellationToken); return(task); }
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(); }