我的应用程序中有一个TextBox,它用于显示进程状态。像这样的东西
for(...)
textbox.text = "new line \r\n" + textbox.text
问题是,当它填充时,所以没有文字可见,只有白色背景。完成处理后,可以看到所有添加的文本。有任何选择,如何解决这个问题(我需要在整个过程中看到文字)。
非常感谢。
答案 0 :(得分:2)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerAsync();
}
delegate void Temp();
void bg_DoWork(object sender, DoWorkEventArgs e)
{
Temp temp = new Temp(UpdateTextBox);
while (true)
{
Thread.Sleep(1000);
textBox1.BeginInvoke(temp);
}
}
void UpdateTextBox()
{
textBox1.Text += "+";
}
}
答案 1 :(得分:0)
如果是winforms,请在循环中添加Application.DoEvents();
,以便您的应用程序可以刷新UI。
这是最简单但不是最佳的方法。
编辑:有人在没有解释方式的情况下对这个问题进行了贬低。那是公平的。问题海报知道backroundworker并想要一个更简单的解决方案。
无论如何,根据循环的性质,这个解决方案可以是完美的。如果它是一个包含大量迭代的循环,每个循环都需要很短的时间来执行,那么调用Application.DoEvents()将完美地工作。我从自己的经验中知道这一点。因为它是一个循环,所以很可能是这种情况。或者也许可以在循环中添加几个DoEvents()。它只是检查Windows消息队列并参加待处理的工作。
我没有看到用户必须继续处理应用程序的其他部分的任何必要条件。
如果它是一个迭代很少的循环,并且需要花费很长时间来执行每个循环,那么使用线程来完成它是必要的。
但是,请记住,如果一个新手在不完全了解其含义的情况下使用线程就会犯错(我指的是线程安全性)。如果应用程序陷入僵局怎么办?破坏不同线程使用的非线程安全结构怎么样?如果用户在后台线程尚未完成时关闭主窗口该怎么办?让我们认真一点,这个工具可以成为无经验之手的炸弹。
此外,如果您想使用线程,则BackgroundWorker不是唯一的解决方案。
答案 2 :(得分:0)
这是因为只有在方法完成后才刷新UI并且消息泵清除以检查“刷新”消息。
您可以在循环结束时使用Application.DoEvents()。
答案 3 :(得分:0)
使用多线程更新文本框。在您的代码中,更新发生得太快,因此您只能看到白色背景。
答案 4 :(得分:0)
您的循环阻止了主UI线程。因此,一旦控件离开循环,UI就会立即更新。我想你应该在这里使用BackgroundWorker
。您的问题已在此article中得到充分讨论。希望它会有所帮助。
答案 5 :(得分:0)
您需要使用BackgroundWorker
从其他线程更新您的gui并让GUI自行运行(因为您可以在GUI中执行其他操作,例如单击复选框或查看其他内容)。然后使用LogBoxTextAdd
方法从另一个线程更新TextBox
,这样就不会导致Cross-Thread
错误。
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApplication4 {
public partial class Form1 : Form {
private readonly BackgroundWorker bg = new BackgroundWorker();
public Form1() {
InitializeComponent();
bg.DoWork += doWork;
}
private void doWork(object sender, DoWorkEventArgs e) {
for (int i = 0; i < 15; i++) {
LogBoxTextAdd("TEST");
}
}
private void LogBoxTextAdd(string varText) {
if (InvokeRequired) {
textBox1.Invoke(new MethodInvoker(() => LogBoxTextAdd(varText)));
} else {
textBox1.Text = varText + "\r\n" + textBox1.Text;
}
}
private void button1_Click(object sender, EventArgs e) {
bg.RunWorkerAsync();
}
}
}