昨天一個朋友問我一個問題,需求是
this.textBox1.Text = "睡眠前";
Thread.Sleep(1000);
this.textBox1.Text = "睡眠後";
他想要的效果就是在顯示的時候先顯示第一個文字 然後睡眠一秒鐘之後 顯示第二文字,我們知道在單執行緒裡面 線上程沒有結束的時候是不可能顯示出任何內容改變的,他的大部分內容還沒有被cpu執行完畢,放在堆疊裡面,這時候是不可能顯示的,那既然提出來了 這邊肯定想要解決掉 那隻能啟動多執行緒,讓主執行緒先跑完 再讓子執行緒去改 這樣就可以解放窗體不能操作的問題了 但是 真的是這樣嗎
private void button1_Click(object sender, EventArgs e)
{
this.textBox1.Text = "睡眠前";
Task.Run(() => { Thread.Sleep(1000); this.textBox1.Text = "睡眠後"; });
}
我們這樣修改一下程式碼 理論上覺得 可以,但是執行發現 根本沒反應,問題出現在哪呢 ,就是子執行緒修改不動主執行緒裡面的東西,這樣一來那我們是不是找到那個主執行緒 就行了呢
這裡我們使用委託
delegate void SetTextCallback(string text);
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
this.textBox1.Text = "睡眠前";
// Task.Run(() => { Thread.Sleep(1000); this.textBox1.Text = "睡眠後"; });
// SetTextCallback SetTextCallback;
// SetTextCallback = SetText;
Task.Run(() => { SetText("睡眠後"); }); }
private void SetText(string text)
{
//子執行緒睡眠1秒
Thread.Sleep(1000);
if (this.textBox1.InvokeRequired)
{
SetTextCallback Callback = new SetTextCallback(SetText);
this.Invoke(Callback, new object[] { text });
}
else
{
this.textBox1.Text = text;
this.textBox1.Refresh();
}
}
這樣 我們通過非同步執行,讓子執行緒通過textbook提供的InvokeRequired屬性去判斷 當前執行緒是否是在主執行緒內 不是的話就通過委託回撥然到主執行緒裡面去修改屬性
以上是我個人理解 如果有什麼不對的地方可以和我交流一下
小白留