Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 控件在调用其调用方法后不会更新_C#_Multithreading - Fatal编程技术网

C# 控件在调用其调用方法后不会更新

C# 控件在调用其调用方法后不会更新,c#,multithreading,C#,Multithreading,已编辑并要求重新打开 我的问题被搁置了,因为它被认为是离题的,我没有添加任何源代码。在我看来,没有必要添加源代码,因为我写了一个简单的问题,没有任何源代码都可以回答:“现在,我的假设是线程被终止,因此调用不再被调用。这是否合理?”这个问题已经得到了回答,我知道这不是原因。当时添加一些源代码是有意义的。我认为现在这个问题应该符合你的要求(尽管我仍然认为一开始不是这样:-)。无论如何,你能重新回答这个问题吗 结束要求重新打开的请求 我有一个C#程序,我想从另一个线程更新两个控件。 第一次更新运行得很

已编辑并要求重新打开

我的问题被搁置了,因为它被认为是离题的,我没有添加任何源代码。在我看来,没有必要添加源代码,因为我写了一个简单的问题,没有任何源代码都可以回答:“现在,我的假设是线程被终止,因此调用不再被调用。这是否合理?”这个问题已经得到了回答,我知道这不是原因。当时添加一些源代码是有意义的。我认为现在这个问题应该符合你的要求(尽管我仍然认为一开始不是这样:-)。无论如何,你能重新回答这个问题吗

结束要求重新打开的请求

我有一个C#程序,我想从另一个线程更新两个控件。 第一次更新运行得很好。文本按预期显示。但是第二个文本框不再填充。第二个调用完全在线程的“末尾”调用

如果我在调用后添加一个
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
    }
label2中的文本仅在执行MessageBox.Show命令时显示(标记为/*****/)

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

处于“线程末尾”不会有任何区别。调用是同步调用的,这意味着您的代码将等待完成。我认为您的代码中存在不同的问题。发布它!现在正如您所说的那样…我将修改它。(我从互联网上截取了一些片段,没有过多考虑这是否有意义。)也许,不需要一个
进程
…如果你把这个作为答案写,我会把它标记为正确答案。谢谢。实际上我需要创建一个新的进程,因为我正在运行一个控制台应用程序,这肯定是一个新的进程。当然,我可以创建一个单独的线程,然后在该线程中启动控制台应用程序,但我不能他还将创建一个单独的进程,所以如果创建了一个新的进程,就不需要再创建新的线程。我认为这样可以节省资源,让事情更清楚。