调用其调用方法

时间:2015-11-30 10:32:08

标签: c# multithreading

已编辑并要求重新开启

我的问题已被搁置,因为它被认为是偏离主题的,我没有添加任何源代码。在我看来,没有必要添加源代码,因为我写了一个简单的问题,可以在没有任何源代码的情况下回答:"现在,我的假设是线程被终止,因此,不再调用调用。这个问题是否明智?" 这个问题已得到解答,我了解到这不是原因。那时添加一些源代码是有意义的。我认为现在这个问题应该满足你的要求(尽管我仍然认为一开始并非如此:-))无论如何,你能否重新打开这个问题?

结束要求重新开启

我有一个C#程序,我想从另一个线程更新两个控件。 第一次更新工作得很好。文本按其预期显示。但是第二个文本框不再填充。第二次调用在" end"线程。

如果我在调用调用后添加MessageBox.Show("..."),则会填充。 现在,我的假设是线程被终止,因此,不再调用调用。 这听起来合情合理吗? 即使在线程结束时,我该怎么做才能使文本框更新?

这里是代码(或:部分内容)

按下按钮后调用任务:

    private void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;
        proc = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = AppDomain.CurrentDomain.BaseDirectory + "\\iperf3.exe",
                Arguments = "[...]",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true,
                RedirectStandardError = true
            }
        };
        proc.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
        proc.ErrorDataReceived += new DataReceivedEventHandler(ErrorHandler);
        proc.Exited += new EventHandler(ExitHandler);
        proc.EnableRaisingEvents = true;

        proc.Start();
        proc.BeginOutputReadLine();
        proc.BeginErrorReadLine();
    }

完成此过程后,它会调用ExitHandler方法(后者又会启动一个新进程:

    private void ExitHandler(object sender, EventArgs e)
    {
        proc.CancelErrorRead();
        proc.CancelOutputRead();
        proc.Dispose();
        proc = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = AppDomain.CurrentDomain.BaseDirectory + "\\iperf3.exe",
                Arguments = "[...]",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true,
                RedirectStandardError = true
            }
        };
        proc.OutputDataReceived += new DataReceivedEventHandler(OutputHandler2);
        proc.ErrorDataReceived += new DataReceivedEventHandler(ErrorHandler);
        proc.Exited += new EventHandler(ExitHandler2);
        proc.EnableRaisingEvents = true;

        proc.Start();
        proc.BeginOutputReadLine();
        proc.BeginErrorReadLine();
    }

第二个线程完成后,将启动以下方法:

    private void ExitHandler2(object sender, EventArgs e)
    {
        MessageBox.Show("Command exited.", "Information"); // When commenting this line, labl2 is not filled anymore, see below /*****/
        proc.CancelErrorRead();
        proc.CancelOutputRead();
        button1.Invoke(new Action(() => button1.Enabled = true));
        proc.Dispose();
    }

文本框的更新是通过解析进程的输出来完成的。这些由OutputHandler方法接收:

首要任务:

    void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        ...
        label1.Invoke(new Action(() => label1.Text = "[some captured text]")); // This part is always working
        ...
    }

并且类似于第二项任务:

    void OutputHandler2(object sendingProcess, DataReceivedEventArgs outLine)
    {
        ...
        label2.Invoke(new Action(() => label2.Text = "[some captured text]"));  // This one is only working when showing a MessagBox on ExitHandler2
    }

只有在执行MessageBox.Show命令时才会显示label2中的文本(用/ ***** /标记)

解决方案 由于我不能将此作为问题的答案添加,我在此处添加。也许这对某人有帮助。 在对代码进行了几天不同的更改之后,我发现proc.CancelOutputRead();指令阻止了表单的更新。似乎在输出读取停止时尚未完全解析输出。删除此指令(以及proc.Dispose()指令时,值会正确显示。 然后,proc.Dispose()调用将在主窗体的onClosing事件处理程序中进行。 感谢您的支持!

0 个答案:

没有答案