Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#ProcessStartInfo.Start-读取输出,但超时_C#_.net - Fatal编程技术网

c#ProcessStartInfo.Start-读取输出,但超时

c#ProcessStartInfo.Start-读取输出,但超时,c#,.net,C#,.net,如果要启动另一个进程并等待(超时)完成,可以使用 如果要启动另一个进程并读取其输出,则可以使用 如何将两者结合起来读取所有输入,而不陷入死锁并在运行进程出错时超时?您不必将两者结合起来-当输出发送到标准输出时,进程类会触发一个事件 如果您订阅了该事件,您将能够在它到达时读取输出,并且在主程序循环中您仍然可以超时。只需将第一个示例的所有内容添加到第二个示例中。您也可以使用APM,如下所示: ReadToEndDelegate asyncCall = reader.ReadToEnd; IAsync

如果要启动另一个进程并等待(超时)完成,可以使用

如果要启动另一个进程并读取其输出,则可以使用


如何将两者结合起来读取所有输入,而不陷入死锁并在运行进程出错时超时?

您不必将两者结合起来-当输出发送到
标准输出时,
进程
类会触发一个事件


如果您订阅了该事件,您将能够在它到达时读取输出,并且在主程序循环中您仍然可以超时。

只需将第一个示例的所有内容添加到第二个示例中。

您也可以使用APM,如下所示:

ReadToEndDelegate asyncCall = reader.ReadToEnd;
IAsyncResult asyncResult = asyncCall.BeginInvoke(null, null);
asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(10));
asyncCall.EndInvoke(asyncResult);
为ReadToEnd调用定义委托:

private delegate string ReadToEndDelegate();
然后使用委托调用方法,如下所示:

ReadToEndDelegate asyncCall = reader.ReadToEnd;
IAsyncResult asyncResult = asyncCall.BeginInvoke(null, null);
asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(10));
asyncCall.EndInvoke(asyncResult);

编辑:为清晰起见,已删除错误处理。

如果输出缓冲区中填充的数据超过4KB,则此技术将挂起。一种更简单的方法是注册代理,以便在将某些内容写入输出流时收到通知:


您可以尝试将第一个方法修改为如下内容

Process p = Process.Start(pInfo);
string output = string.Empty;
Thread t = new Thread(() =>  output = p.StandardOutput.ReadToEnd() );
t.Start();
//Wait for window to finish loading.
p.WaitForInputIdle();
//Wait for the process to exit or time out.
p.WaitForExit(timeOut);

如果执行此操作,请不要忘记在Process类上设置EnableRaisingEvents属性。每次都获取我。根据MSDN doco EnableRaisingEvents仅适用于已退出的事件,而不是OutputDataReceived。我想知道为什么OutputDataReceived事件从未触发。。。似乎太快地投票给了约翰奇。什么是先准备后结束还是等待退出?想详细说明一下吗?说要注册参加活动的答案比我的好。我会这样做,而不是你可能对库感兴趣,它使处理进程io流和为进程分配超时变得容易。请解释如何找出接收到的数据何时完成。在
WaitForExit
返回并且程序继续运行之后,我一直收到这些事件。接收到的数据不完整,因此不安全。我可以在接收较长的输出(短输出总是可以的)时观察到挂起(进程不会及时退出),因此同步读取挂起可能是真的。
ProcessStartInfo processInfo = new ProcessStartInfo("Write500Lines.exe");
processInfo.ErrorDialog = false;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;

Process proc = Process.Start(processInfo);

// You can pass any delegate that matches the appropriate 
// signature to ErrorDataReceived and OutputDataReceived
proc.ErrorDataReceived += (sender, errorLine) => { if (errorLine.Data != null) Trace.WriteLine(errorLine.Data); };
proc.OutputDataReceived += (sender, outputLine) => { if (outputLine.Data != null) Trace.WriteLine(outputLine.Data); };
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();

proc.WaitForExit();
Process p = Process.Start(pInfo);
string output = string.Empty;
Thread t = new Thread(() =>  output = p.StandardOutput.ReadToEnd() );
t.Start();
//Wait for window to finish loading.
p.WaitForInputIdle();
//Wait for the process to exit or time out.
p.WaitForExit(timeOut);
void OpenWithStartInfo()
{
    ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe", "Default2.aspx");
    startInfo.WindowStyle = ProcessWindowStyle.Minimized;
    Process p = Process.Start(startInfo);
    p.WaitForInputIdle();  
    //p.WaitForExit(2);
    p.Kill();
}