我正在通过exe执行BCP命令,并且在复制50000行后卡住了。 我看了一些论坛并且知道如果我们在代码中使用StandardOuputReader而不是它的最大输出限制接近50000行,这也发生在我身上 有没有办法我运行重定向输出超过50000行可以出来。
此代码可以在这里使用
proc.StartInfo.RedirectStandardOutput = false;
但是我想让它成为现实,看看输出。
private static void RunBatch(string Fullfilepath, string BatchFilePathDumpFlatFile)
{
mLogger.Error("RunBatch Start=== >");
mLogger.Error("Batch Filepath " + Fullfilepath + '\n' + "Batch File Directory " + BatchFilePathDumpFlatFile);
Process proc = null;
string targetDir = BatchFilePathDumpFlatFile;
proc = new Process();
proc.StartInfo.WorkingDirectory = targetDir;
proc.StartInfo.FileName = Fullfilepath;
//proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "/c";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = false;
proc.Start();
proc.WaitForExit();
string output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();
mLogger.Error("Output from batch " + output);
mLogger.Error("Error From Batch " + error);
}
更新1:
private static void RunBatch(string Fullfilepath, string BatchFilePathDumpFlatFile)
{
mLogger.Error("RunBatch Start=== >");
mLogger.Error("Batch Filepath " + Fullfilepath + '\n' + "Batch File Directory " + BatchFilePathDumpFlatFile);
Process proc = null;
string targetDir = BatchFilePathDumpFlatFile;
proc = new Process();
proc.StartInfo.WorkingDirectory = targetDir;
proc.StartInfo.FileName = Fullfilepath;
//proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "/c";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();
mLogger.Error("Output from batch " + output);
mLogger.Error("Error From Batch " + error);
}
我正在使用的是有一个错误,因为仍然BCP挂起并且当我停止代码的exe时它开始运行。
答案 0 :(得分:2)
这是典型的死锁条件。在完全阅读WaitForExit
之前,您不应致电StandardOutput
。
当重定向输出时,进程不会在读取所有StandardOutput
流之前终止。因此,调用WaitForExit
将等待已启动的进程终止,并且子进程将等待父进程完全读取输出流,然后才能完成并因此死锁。
Msdn提供了解释和代码示例以避免死锁。
同步读取操作在从StandardOutput流读取调用者和写入该流的子进程之间引入依赖关系。这些依赖项可能导致死锁条件。当调用者从子进程的重定向流中读取时,它依赖于子进程。调用者等待读操作,直到子进程写入流或关闭流。当子进程写入足够的数据来填充其重定向流时,它依赖于父进程。子进程等待下一个写操作,直到父进程从完整流中读取或关闭流。当调用者和子进程等待彼此完成操作时,将导致死锁条件,并且两者都无法继续。您可以通过评估调用者和子进程之间的依赖关系来避免死锁。
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
代码示例通过在p.WaitForExit之前调用p.StandardOutput.ReadToEnd来避免死锁条件。如果父进程在p.StandardOutput.ReadToEnd之前调用p.WaitForExit并且子进程写入足够的文本来填充重定向的流,则可能导致死锁条件。父进程将无限期地等待子进程退出。子进程将无限期地等待父进程从完整的StandardOutput流中读取。
当您从标准输出和标准错误流中读取所有文本时,存在类似的问题。例如,以下C#代码对两个流执行读操作。
// Do not perform a synchronous read to the end of both
// redirected streams.
// string output = p.StandardOutput.ReadToEnd();
// string error = p.StandardError.ReadToEnd();
// p.WaitForExit();
// Use asynchronous read operations on at least one of the streams.
p.BeginOutputReadLine();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();
以上几乎所有内容都来自msdn,我建议你完全阅读它以避免进一步造成死锁。