private void RaiseOnProcessEnd(string id, bool success, Exception ex, string errors) { if (cts.IsCancellationRequested) { return; } if (processes.TryGetValue(id, out var context) && context.Client != null) { if (!success && ex != null && ex is ProcessException pe && pe.InnerException is Win32Exception) { // don't keep alive this process, it's not starting up correctly UpdateMonitorOptions(id, MonitorOptions.None); } taskManager .WithAsync(async ctx => { var data = new NotificationData(ctx.Client.GetRemoteTarget <IProcessNotifications>(), RpcProcessEndEventArgs.Get(ctx.Process, success, ex.GetExceptionMessage(), (ex as ProcessException)?.ErrorCode ?? 0, ex?.GetType().ToString() ?? string.Empty, errors)); await data.notifications.ProcessOnEnd(data.EndArgs); return(0); }, context, TaskAffinity.Custom) .Start(context.Notifications); } }
private void RaiseOnProcessEnd(RpcProcessEndEventArgs args) { if (!wrappers.TryGetValue(args.Process.Id, out var list) || !schedulers.TryGetValue(args.Process.Id, out var scheduler)) { throw new InvalidOperationException( $"OnEnd for process {args.Process.Id} was called but there's no record of it in the process list."); } foreach (var wrapper in list) { var task = new Task(s => wrapper.OnProcessEnd((RpcProcessEndEventArgs)s), args, cts.Token, TaskCreationOptions.None); if (args.Process.ProcessOptions.MonitorOptions != MonitorOptions.KeepAlive) { task.ContinueWith((_, __) => { lock (schedulers) { if (wrappers.ContainsKey(args.Process.Id)) { schedulers.Remove(args.Process.Id); wrappers.Remove(args.Process.Id); scheduler.Dispose(); ((ThreadSynchronizationContext)scheduler.Context).Dispose(); } } }, null, cts.Token, TaskContinuationOptions.None, TaskScheduler.Default); } task.Start(scheduler); } }
public void OnProcessEnd(RpcProcessEndEventArgs e) { if (disposed) { return; } if (!e.Successful) { thrownException = !string.IsNullOrEmpty(e.Exception) ? new ProcessException(e.Exception) : null; } // the task is completed if the process server isn't going to restart it, we can finish up if (e.Process.ProcessOptions.MonitorOptions != MonitorOptions.KeepAlive) { cts.Cancel(); } }
public NotificationData(IProcessNotifications notifications, RpcProcessEndEventArgs args) { this.notifications = notifications; this.args = args; }
public Task ProcessOnEnd(RpcProcessEndEventArgs args) { manager.RaiseOnProcessEnd(args); return(Task.CompletedTask); }