在方法运行时,Richbox不会更新

时间:2016-02-19 06:21:02

标签: c# winforms

抱歉标题不合适。我的程序如下

int status = 100;
richTextBox1.AppendText("Starting Process....." + "\n");

status = comm.WriteData(cmd1);
if (status == 0)
{
    richTextBox1.AppendText("COMMAND 1 OK" + "\n");
}
else
{
    richTextBox1.AppendText("COMMAND 1 NOT OK" + "\n");
}
richTextBox1.AppendText("Gathering signal from product sensor....." + "\n");
status = comm.WriteData(cmd2);
if (status == 0)
{
    richTextBox1.AppendText("COMMAND 2 OK" + "\n");
}
else
{
    richTextBox1.AppendText("COMMAND 2 NOT OK" + "\n");
}
richTextBox1.AppendText("Measuring current value" + "\n");
status = comm.WriteData(cmd3);
if (status == 0)
{
    richTextBox1.AppendText("COMMAND 3 OK" + "\n");
}
else
{
    richTextBox1.AppendText("COMMAND 3 NOT OK" + "\n");
}

这将在按钮点击事件上执行。像这样我需要发送130个命令。整个过程大约需要6分钟。代码工作正常。但是在执行所有命令(持续6分钟)之前,RichTextBox似乎是空的。在执行每个命令后,我需要向操作员显示消息,无论命令是OK还是NOT OK。我甚至试过在每个命令之间给出延迟。但不能达到我的需要。请支持解决此问题。

3 个答案:

答案 0 :(得分:3)

您需要在单独的线程中编写数据。发生了什么事情是您的UI线程正在等待执行您的功能,然后才能恢复正常操作,例如更新控件。您可以在winforms BackgroundWorker Class的文档中阅读更多内容。

答案 1 :(得分:3)

我在这里使用BackgroundWorker,并使用ReportProgress添加到文本框中。像(在我脑海里)的东西:

public void ButtonClick()
{
   // Since your code will now be async, you should need to handle reentrance here
   var worker = new BackgroundWorker();
   worker.ReportsProgress = true;
   worker.ProgressChanged += ProgressLog;
   worker.DoWork += TestComm;
   worker.RunWorkerAsync();
}

private void ProgressLog(object sender, ProgressChangedEventArgs e)
{
   richTextBox1.AppendText(e.UserState.ToString() + Environment.NewLine);
}

private void TestComm(object sender, DoWorkEventArgs e)
{         
   var worker = sender as BackgroundWorker;
   worker.ReportProgress(0, "Starting Process.....");
   // Sub-optimal way to construct a string :-)
   worker.ReportProgress(0, "COMMAND 1 " + (comm.WriteData(cmd1) == 0 ? "OK" : "NOT OK"));
   worker.ReportProgress(0, "Gathering signal from product sensor.....");
   worker.ReportProgress(0, "COMMAND 2 " + (comm.WriteData(cmd2) == 0 ? "OK" : "NOT OK"));
   worker.ReportProgress(0, "Measuring current value");
   worker.ReportProgress(0, "COMMAND 3 " + (comm.WriteData(cmd3) == 0 ? "OK" : "NOT OK"));
   // etc.
}

作为旁注,如果您所做的只是"显示标题字符串","运行命令",写"命令#ok / not ok",这可以很容易地重构成一个循环,但我会留给你: - )

此外,由于您的代码现在是异步的,因此您需要处理重新按钮的Click事件,因为用户现在可以在测试运行时单击该按钮(因此会同时运行两个测试,如果你使用的是通信端口,可能是不可能的。)

这可能就像创建工作程序时禁用按钮一样简单,并在BackgroundWorker.RunWorkerCompleted事件上再次启用它,或者您可以根据需要使其复杂化(取消初始测试并再次启动它) ,或什么)。

正如评论中所述,您还需要有关重入的帮助。最简单的方法是:

public void ButtonClick()
{
   // Disable the button       
   myButton.Enabled = false;

   var worker = new BackgroundWorker();
   worker.ReportsProgress = true;
   worker.ProgressChanged += ProgressLog;
   worker.DoWork += TestComm;

   // Re-enable the button when the worker has completed (or failed)
   worker.RunWorkerCompleted += (o,e) => myButton.Enabled = true;
   worker.RunWorkerAsync();
}

答案 2 :(得分:1)

在每个AppendText后尝试此代码:

richTextBox1.Refresh();