C # Процесс удаления утилизации Стандартная ошибка не была перенаправлена - PullRequest
1 голос
/ 30 ноября 2011

Я создаю объект Process для запуска процесса с ProcessStartInfo с правильным набором свойств. Это работало, пока я не подумал об утилизации объекта Process. Первоначально я обернул его вокруг блока using, и это не удалось, после чего я явно вызвал Close и Dispose в обработчике Exited Event.

Код выглядит следующим образом:

var processInfo = new ProcessStartInfo("program.exe", argument)
{
    RedirectStandardError = true,
    CreateNoWindow = true,
    UseShellExecute = false
};
var proc = new Process { StartInfo = processInfo, EnableRaisingEvents = true };
proc.Exited += EventHandler;
proc.Start();
proc.WaitForExit();

private static void EventHandler(object sender, EventArgs e)
{
    var p = sender as Process;
    if (p == null)
        return;
    var stdErr = p.StandardError.ReadToEnd();
    if (!string.IsNullOrEmpty(stdErr))
        Console.WriteLine(string.Format("Log:({0}) {1} ", p.ExitCode, stdErr));
    p.Close();
    p.Dispose();
}

Когда я добавляю p.Close () и p.Dispose (), я получаю следующую ошибку:

System.InvalidOperationException : StandardError has not been redirected.
   at System.Diagnostics.Process.get_StandardError()

StackTrace следующим образом:

Unhandled exception in remote appdomain: System.InvalidOperationException: StandardError has not been redirected.
   at System.Diagnostics.Process.get_StandardError()
   at namespace.EventHandler(Object sender, EventArgs e) in c:\BuildAgent\work\70df16b46ad15c54\Source\Blah.cs:line 318
   at System.Diagnostics.Process.OnExited()
   at System.Diagnostics.Process.RaiseOnExited()
   at System.Diagnostics.Process.CompletionCallback(Object context, Boolean wasSignaled)
   at System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context(Object state, Boolean timedOut)
   at System.Threading._ThreadPoolWaitOrTimerCallback.WaitOrTimerCallback_Context_f(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)

Даже следующий код выдает то же исключение:

var processInfo = new ProcessStartInfo("program.exe", argument)
{
    RedirectStandardError = true,
    CreateNoWindow = true,
    UseShellExecute = false
};
using(var proc = new Process { StartInfo = processInfo, EnableRaisingEvents =true })
{
    proc.Exited += EventHandler;
    proc.Start();
    proc.WaitForExit();
}

private static void EventHandler(object sender, EventArgs e)
{
    var p = sender as Process;
    if (p == null)
        return;
    var stdErr = p.StandardError.ReadToEnd();
    if (!string.IsNullOrEmpty(stdErr))
        Console.WriteLine(string.Format("Log:({0}) {1} ", p.ExitCode, stdErr));

}
...