我在我的應用程序中有一個TextBox,它用於顯示進程的狀態。像這樣的東西TextBox填充C#
for(...)
textbox.text = "new line \r\n" + textbox.text
問題是,它填充時,所以沒有文字可見,只是白色的背景。處理完成後,所有添加的文本都可見。有什麼選擇,如何解決這個問題(我需要在整個過程中看到文字)。
非常感謝。
我在我的應用程序中有一個TextBox,它用於顯示進程的狀態。像這樣的東西TextBox填充C#
for(...)
textbox.text = "new line \r\n" + textbox.text
問題是,它填充時,所以沒有文字可見,只是白色的背景。處理完成後,所有添加的文本都可見。有什麼選擇,如何解決這個問題(我需要在整個過程中看到文字)。
非常感謝。
如果是winforms,請在循環中添加Application.DoEvents();
,以便您的應用程序可以刷新UI。
這是最簡單但不是最佳的方法。
編輯:有人已經downvoted這個問題沒有解釋的方式。這很公平。問題海報知道backroundworker並想要一個更簡單的解決方案。
無論如何,這個解決方案可以完美取決於循環的性質。如果它是一個循環,每個循環都需要很短的時間來執行,那麼調用Application.DoEvents()將會很好地工作。我從我自己的經歷中瞭解到這一點。由於這是一個循環,很可能是這種情況。或者也許可以在循環中添加幾個DoEvents()。它只是檢查窗口消息隊列並參加待處理的工作。
我沒有看到用戶必須繼續在應用程序的其他部分工作的任何必要條件。
如果它是一個迭代次數很少的循環,並且需要很長時間才能執行每個循環,那麼使用線程就可以完成它。
但是,要記住,如果一個新手在不知道其含義的情況下使用線程(我稱之爲線程安全),那麼新手可能會犯錯誤。如果應用程序陷入僵局會怎麼樣?如何破壞不同線程中使用的非線程安全結構?如果用戶在後臺線程尚未完成時關閉主窗口會怎麼樣?讓我們認真的,這個工具可以是一個無經驗的手中的炸彈。
此外,如果你想使用線程BackgroundWorker不是唯一的解決方案。
那是因爲只有在方法完成並且消息泵清除以檢查「刷新」消息後纔會刷新UI。
您可以在循環結尾使用Application.DoEvents()。
使用多線程來更新您的文本框。在你的代碼更新發生得太快,所以你只看到白色背景。
你的循環阻塞了主UI線程。因此,一旦控制離開循環,UI即刻更新。我想你應該在這裏使用BackgroundWorker
。你的問題在這article討論得很好。希望這會有所幫助。
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 += "+";
}
}
您需要使用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();
}
}
}
您正在使用哪種UI框架? Windows窗體,WPF,ASP.Net? – Botz3000 2012-03-23 10:54:36
這是因爲你阻止了for循環中的主線程(它負責繪製和更新表單)。您需要分離一個單獨的工作線程來處理數據,並將消息發送到主窗體以更新文本框,以便您的主線程保持自由刷新。 – 2012-03-23 10:55:54
問題已解決。我知道BackgroundWorker,但正在尋找一些更簡單的解決方案,如Application.DoEvents()。 感謝所有的快速答案。 – user1288050 2012-03-23 11:48:34