2010-05-22 39 views
0

我正在做一些線程實驗,並且做了一個'控制'方法來比較所有處理在UI線程中發生的位置。它應該運行一個方法,在最後更新一個標籤。此方法運行四次,但標籤在所有4個完成之前不會更新。我希望一個標籤每2秒更新一次。這裏的代碼:爲什麼不立即贏取表單應用程序更新標籤?

private void button1_Click(object sender, EventArgs e) 
{ 
    Stopwatch watch = new Stopwatch(); 
    watch.Start(); 

    UIThreadMethod(lblOne); 
    UIThreadMethod(lblTwo); 
    UIThreadMethod(lblThree); 
    UIThreadMethod(lblFour); 

    watch.Stop(); 
    lblTotal.Text = "Total Time (ms): " + watch.ElapsedMilliseconds.ToString(); 
} 

private void UIThreadMethod(Label label) 
{ 
    Stopwatch watch = new Stopwatch(); 
    watch.Start(); 

    for (int i = 0; i < 10; i++) 
    { 
     Thread.Sleep(200); 
    } 
    watch.Stop(); 

    // this doesn't set text right away 
    label.Text = "Done, Time taken (ms): " + watch.ElapsedMilliseconds; 
} 

也許我只是缺少一些基本的東西,但我卡住了。有任何想法嗎?謝謝。

+0

嘗試[Application.DoEvents()](HTTP:// MSDN .microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx)? – Patrick 2010-05-22 19:46:56

回答

5

你的UI線程是一個單線程,而不是兩個線程。爲了讓你的UI響應,你必須把工作放在另一個線程上(通常是BackgroundWorker),或者告訴UI在UI線程中重繪自己。

我一直有,當我做這樣的事情做實驗,但Control.Refresh方法應該這樣做:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.refresh.aspx

+0

謝謝,添加'Refresh();'使它工作,但這是否意味着任何處理UI線程都會始終執行UI更新? – rosscj2533 2010-05-22 19:10:22

+0

@ rossch2533:既然是一個線程,是的,而且由於繪畫是一項繁瑣的任務,通常不會執行,除非必須執行。當涉及到UI觸發事件時,繪畫就會在完成這些方法後執行,從而爲方法留下寶貴的CPU週期,而不是在繪畫時「減少它們」。你當然可以繞過這個,例如使用'Refresh'方法,但是你是一個決定。 – Patrick 2010-05-22 19:57:37

+0

@帕特里克,謝謝,這清除了我的疑惑,答案不明確。 – rosscj2533 2010-05-23 16:48:13

2

您正在通過執行睡眠操作來阻止UI線程,這會導致不會重繪。如果你想睡在另一個線程上並在UI線程上調用標籤更新,那麼它應該按預期工作。

+0

謝謝,我可以看到它使用不同的線程來運行'UIThreadMethod',但爲什麼'Thread.Sleep'防止重繪?如果只是需要2秒才能完成的代碼,它會有什麼不同嗎? – rosscj2533 2010-05-22 19:13:00

+0

好吧,Thread.Sleep導致你當前的線程什麼都不做。因爲當前線程是UI線程,所以UI不執行任何操作,因此不執行任何重繪。 – Thomas 2010-05-24 08:42:04

相關問題