标准输出阅读器挂起BCP工具

时间:2014-12-26 15:36:33

标签: c# .net windows cmd bcp

我正在通过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时它开始运行。

1 个答案:

答案 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,我建议你完全阅读它以避免进一步造成死锁。