C# Process Dispose 抛出标准错误未重定向
我正在创建一个 Process 对象,以使用具有正确属性集的 ProcessStartInfo 来运行进程。在我考虑处理我的 Process 对象之前,这种方法一直有效。最初,我将其包装在 using 块中,但失败了,之后我在退出事件处理程序中显式调用 Close 和 Dispose。
代码如下所示:
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));
}
I am crating a Process object to run a process with a ProcessStartInfo with the correct properties set. This was working until I thought about disposing my Process object. Initially I wrapped it around a using block and that failed after which I explicitly call Close and Dispose in the Exited Event Handler.
The code looks like follows:
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();
}
When I add the p.Close() and p.Dispose() I get the following error:
System.InvalidOperationException : StandardError has not been redirected.
at System.Diagnostics.Process.get_StandardError()
StackTrace as follows:
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)
Even the following code throws the same exception:
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));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论