【问题标题】:Reading StdOut Asynch from a c console app从 c 控制台应用程序读取 StdOut 异步
【发布时间】:2010-09-09 19:27:45
【问题描述】:

我有一个基于控制台的 c 应用程序。 我正在使用重定向标准输出从 c# 静默执行它并同步执行它,效果很好。 现在我想以异步方式执行此操作,即提供同步方式的输出。 IE OutPutDataRecieved 事件被触发,但仅在控制台应用程序(exe)完成后触发。OutputDataRecieved 事件在完成后为每一行触发,而不是在输出中得到一行后立即触发。

异步代码适用于 CMD.exe 等,因此,我确信它的基于 c 的应用程序在输出中存在问题。 仅供参考:c 控制台中的输出是使用 printf 完成的。 根据我的发现: 我认为 c 控制台应用程序在完成执行之前不会向标准输出提供输出/写入。 我尝试在每次 printf 后将缓冲区设置为 null 或刷新,但没有任何效果。

有什么技巧吗??

【问题讨论】:

  • 愿意发布您的 C# 代码的相关部分吗?
  • 您有C 和c# 应用程序的源代码吗?如果您显示相关部分,也许会有所帮助。
  • 当你说你将缓冲区设置为null时,你是在使用setvbuf函数吗?
  • C 运行时库在看到 stdout 流被重定向时会对其进行缓冲。只有当缓冲区填满并需要刷新时,您才能看到输出。或者当标准输出关闭时。

标签: c# c process console asynchronous


【解决方案1】:

谢谢老兄。这就像一个魅力。

我正在使用 setbuf 将缓冲区设置为空。

真的很感谢你们所有人的努力。

对于其他人的信息,这是我的 c# 代码,可以在互联网论坛和 SO 上找到。

        string command = @"Output.exe"; 
  string arguments = "hellotext"; 

  ProcessStartInfo info = new ProcessStartInfo(command, arguments); 

  // Redirect the standard output of the process.  
  info.RedirectStandardOutput = true; 
  info.RedirectStandardError = true; 

  // Set UseShellExecute to false for redirection 
  info.UseShellExecute = false; 

  Process proc = new Process(); 
  proc.StartInfo = info; 
  proc.EnableRaisingEvents = true; 

  // Set our event handler to asynchronously read the sort output. 
  proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived); 
  proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived); 
  proc.Exited += new EventHandler(proc_Exited); 

  proc.Start(); 
  // Start the asynchronous read of the sort output stream. Note this line! 
  proc.BeginOutputReadLine(); 
  proc.BeginErrorReadLine(); 

  proc.WaitForExit(); 

  Console.WriteLine("Exited (Main)"); 

} 

static void proc_Exited(object sender, EventArgs e) 
{ 

  Console.WriteLine("Exited (Event)"); 
} 



static void proc_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
{ 
  Console.WriteLine("Error: {0}", e.Data); 
} 



static void proc_OutputDataReceived(object sender, DataReceivedEventArgs e) 
{ 
  Console.WriteLine("Output data: {0}", e.Data); 
} 

【讨论】:

  • @user445066,我很高兴能帮上忙。
【解决方案2】:

您可以使用setvbuf 禁用缓冲。

这是一个简单的示例,如果您删除对setvbuf 的调用,那么重定向的内容只会在您按下回车后写入(等待 getchar())。使用setvbuf,字符串直接写入重定向流。

int _tmain(int argc, _TCHAR* argv[])
{
  setvbuf(stdout, NULL,_IONBF, 0);
  printf("Hello");
  getchar();
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-30
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多