2011-04-12 60 views
9

我有一个多线程的winforms应用程序。一个用于GUI的线程,一个用于后台处理的线程。在后台处理中,我通过Process类与外部进程进行通信以发送接收数据。Process.OutputDataReceived引发并处理了什么线程?

我很困惑我注册Process.OutputDataReceived的处理程序在哪个线程上运行。根据MS文档:“OutputDataReceived事件表示关联的进程已写入其重定向的StandardOutput流。”但是谁也没有明确提出这个事件。

请参见下面的示例代码:

myProc= new Process(); 
myProc.StartInfo.UseShellExecute = false; 
myProc.StartInfo.RedirectStandardOutput = true; 
myProc.StartInfo.RedirectStandardError = true; 
myProc.StartInfo.RedirectStandardInput = true; 
myProc.StartInfo.FileName = "myapp.exe"; 
myProc.StartInfo.Arguments = arguments; 
myProc.StartInfo.CreateNoWindow = true; 
myProc.OutputDataReceived += new DataReceivedEventHandler(DataReceivedFromProc); 
myProc.ErrorDataReceived += new DataReceivedEventHandler(ErrorReceivedFromProc); 
myProc.Start(); 
myOutputStream = myProc.StandardInput; 
myProc.BeginOutputReadLine(); 
myProc.BeginErrorReadLine(); 
在这种情况下

那么,什么线程DataReceivedFromProc上运行?如果上述操作在我的GUI线程vs工作线程上执行,它会有所作为吗?

回答

5

您应该将myProc.SynchronizingObject property设置为您的窗体或控件。

否则,我相信该事件将在IO完成线程(从ThreadPool)中引发。

+0

进程退出事件与进程运行时引发的事件有什么关系? – Josh 2011-04-18 19:19:07

+1

@Josh:所有的事件都以相同的方式提出(我在'internal void OutputReadNotifyUser'中检查了源代码) – SLaks 2011-04-18 19:47:54

+1

另外还有一个关于未来的说明:“如果在Windows窗体设计器中使用Visual Studio 2005内部的进程,SynchronizingObject会自动设置为包含进程的控件。“ – Josh 2011-04-18 20:33:34

1

也可参见在this page最底部用户注释:

Process.OutputDataReceived是在不同的线程比实例化并且被配置为处理对象,并启动该进程的一个凸起。

如果Process对象在主(或UI)线程上实例化,那么将无法从OutputDataReceived事件处理程序更新在该线程上运行的UI。相反,您将不得不使用委托将消息发送到主线程进行处理。