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);
            }
        }
Esempio n. 3
0
        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);
 }