/// <summary> /// Invoked asynchronously when the process has written a line to stdout or stderr. /// Implements a very rough progress estimation system based on the current number /// of output lines and a total estimate. /// </summary> protected override void OnLineWritten(System.Diagnostics.DataReceivedEventArgs e) { const double MIN_PERCENTAGE_DELTA = 0.1; base.OnLineWritten(e); if (_expectedNumOutputLines <= 0 || ProgressChanged == null) { return; } double expectedPercentage; lock (_syncObject) { int numLines = ++_currentNumOutputLines; expectedPercentage = (100.0 * numLines) / _expectedNumOutputLines; if (expectedPercentage - _lastReportedProgressPercentage < MIN_PERCENTAGE_DELTA || _lastReportedProgressPercentage >= 100) // no more progress reports if last percentage >= 100% { return; } expectedPercentage = Math.Min(100, expectedPercentage); // max 100% _lastReportedProgressPercentage = expectedPercentage; } SmartEventInvoker.FireEvent(ProgressChanged, this, new ProgressEventArgs(expectedPercentage)); }
/// <summary> /// Invoked asynchronously when the process has exited. /// </summary> private void OnExited(EventArgs e) { // the Exited event is sometimes triggered a second time // I guess that has to do with disposing of the process in another thread // while the Exited event hasn't been handled completely yet if (Interlocked.Exchange(ref _onExitedInvoked, 1) == 1) { return; } // hijack all (remaining) event handlers from the Exited event EventHandler exitedEventHandlers; lock (_syncObject) { exitedEventHandlers = Exited; Exited = null; } // invoke/dispatch them var iasyncs = SmartEventInvoker.FireEvent(exitedEventHandlers, this, e); int numHandlers = GetNumDelegates(exitedEventHandlers); // incl. dispatched ones int numDispatched = (iasyncs == null ? 0 : iasyncs.Count); int numInvoked = numHandlers - numDispatched; OnExitedEventHandlersFinished(numInvoked); if (numDispatched > 0) { // in a new thread: var thread = new Thread(() => { // wait for all dispatched handlers to complete SmartEventInvoker.Wait(iasyncs); OnExitedEventHandlersFinished(numDispatched); }); thread.Start(); } }
private void OnError(string text) { SmartEventInvoker.FireEvent(Error, this, new TextEventArgs(text)); }
private void OnReady() { SmartEventInvoker.FireEvent(Ready, this, EventArgs.Empty); }
/// <summary> /// Invoked asynchronously when the process has written a line to stdout or stderr. /// </summary> protected virtual void OnLineWritten(DataReceivedEventArgs e) { SmartEventInvoker.FireEvent(LineWritten, this, e); }