コード例 #1
0
        public Job(int id, Process process, JobCallbackInfo callback = null)
        {
            logger.Info("Spawning new job id {0}; will call {1}", id, process.StartInfo.FileName);
            jobId        = id;
            this.process = process;

            // if a progress port was specified in callback info, prepare for streaming
            if (callback != null && callback.ProgressPort > 0)
            {
                var streamEp = new IPEndPoint(callback.Address, callback.ProgressPort);
                CreateProgressStream(streamEp);

                streamingCollection = new BlockingCollection <string>();

                process.OutputDataReceived += (s, a) => streamingCollection.Add(a.Data);
                process.ErrorDataReceived  += (s, a) => streamingCollection.Add(a.Data);

                streamingLoopTask = Task.Factory.StartNew(StreamingLoopHandler);
            }
            else
            {
                output = new HelperFunctions.ThreadSafeStringBuilder();
                process.OutputDataReceived += (s, a) => output.AppendLine(a.Data);
                process.ErrorDataReceived  += (s, a) => output.AppendLine(a.Data);
            }

            // always log output
            process.OutputDataReceived += (s, a) => logger.Debug($"Job {this.jobId} std output: {a.Data}");
            process.ErrorDataReceived  += (s, a) => logger.Debug($"Job {this.jobId} std error: {a.Data}");

            // add a logging message when a job finishes and ensure that streaming task stops if needed
            process.EnableRaisingEvents = true;
            process.Exited += (o, e) => logger.Info($"Job {id} finished executing.");
            process.Exited += (o, e) => streamingCollection?.Add(null);

            if (callback != null)
            {
                logger.Info("Registering job {0:d} for callbacks", id);

                // if callbacks are specified, we need to register for process events, and setup a handler
                callbackInfo = callback;

                // fire the callback handler in another thread (otherwise the callback might take a while and block other events waiting on exit)
                process.Exited += (o, e) => Task.Factory.StartNew(FireCompletionCallback);
            }

            process.Start();

            process.BeginErrorReadLine();
            process.BeginOutputReadLine();
        }