重定向标准错误的 C# 问题

标签 c# multithreading

我的应用程序中的主窗体启动一个新线程,然后打开另一个窗体,用作进度窗口。 该线程在 2 个控制台应用程序之间传输一些数据,并将来自 StandardError 的信息发送到进度窗口。我使用 DataReceivedEventHandler 异步读取标准错误。

如果我让一切顺其自然,它工作得很好,但是当用户按下我表单上的“取消”按钮时就会出现问题。会发生什么,即使在我停止进程后,ErrorDataReceived 函数仍会继续触发!有时取消会成功,但有时我会遇到死锁情况(我认为这是正确的词)。

这是我的一些代码片段,您可以看到发生了什么。它卡在等待“p2.WaitForExit();”和“调用(新的 updateProgressDelegate(this.updateProgress),e.Data);” (visual studio 在这些行旁边放置了一个绿色箭头,并表示它们将是下一个执行的)

// start 2 processes (p & p2) and pipe data from one to the other
// this runs in thread t
                    p.Start();
                    p2.Start();
                    byte[] buf = new byte[BUFSIZE];
                    int read = 0;
                    p2.ErrorDataReceived += new DataReceivedEventHandler(p2_ErrorDataReceived);
                    p2.BeginErrorReadLine();

                    try
                    {
                        read = p.StandardOutput.BaseStream.Read(buf, 0, BUFSIZE);
                        while (read > 0 && read <= BUFSIZE)
                        {
                            if (canceled==false)
                                p2.StandardInput.BaseStream.Write(buf, 0, read);
                            if (canceled==false)
                                read = p.StandardOutput.BaseStream.Read(buf, 0, BUFSIZE);
                            else
                            {
                                return;
                            }
                        }
                    }


// this function is called when a user presses the "cancel" button on a form.
private void cancel_encode()
        {

            if (p2 != null)
            {
                if (p2.HasExited == false)
                    p2.Kill();
                if (p2.HasExited == false)
                    p2.WaitForExit();
            }
            if (p != null)
            {
                if (p.HasExited == false)
                    p.Kill();
                if (p.HasExited == false)
                    p.WaitForExit();
            }
            if (t.IsAlive)
            {
                if (!t.Join(2000))
                    t.Abort();
            }
        }


// this function sends the error data to my progress window
void p2_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null && canceled == false)
                Invoke(new updateProgressDelegate(this.updateProgress), e.Data);
        }

最佳答案

两件事

在“p2_ErrorDataReceived”中,您调用 Invoke()。这可能会导致您的部分僵局。您可能希望将其更改为 BeginInvoke()。

Process.WaitForExit() 的文档建议在调用 Kill() 后,应调用带整数的 WaitForExit 重载,如果返回 true,则再次不带参数调用它,以确保所有异步处理都已完成完成:

 p2.Kill();
 if(p2.WaitForExit(waitTime)) //waitTime is the number of milliseconds to wait
 {p2.WaitForExit();}  //waits indefinitely

 //likewise for p

http://msdn.microsoft.com/en-us/library/ty0d8k56.aspx

关于重定向标准错误的 C# 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1739079/

相关文章:

c - 在 C 中将结构发送到线程

c# - 截至目前,使用 COM 对象的正确方法是什么?

c# - C# 中的 Action 委托(delegate)

c# - .Net Core 3.1 将 Serilog 与 Microsoft.Extensions.Logger 结合使用

c++ - 计算斐波那契数的线程程序

c# - UI 调度缓冲?

c# - 序列化类型化数据集、更新程序集、反序列化错误

c# - 子表单运行时防止初始表单出现 "refreshing"

java - 如何获取当前线程所在线程组的名称

multithreading - Tibco RV 和线程