2011-07-09 55 views
2

我似乎有正確的順序執行命令的問題,我在我的程序的方法:C#方法,說明以正確的順序不執行

private void GenerateButton_Click(object sender, EventArgs e) 
{ 
    Statuslabel.Text = "Working..."; 

    LongMethod(); 
    //Call to another Method of another class which takes 15-20 seconds to execute 

    Statuslabel.Text = "Done"; 
} 

的問題似乎是,而不是分配「工作「狀態標籤,然後調用LongMethod,程序似乎首先執行LongMethod(),然後它將狀態標籤的文本更改爲」工作「一秒鐘,然後立即將其更改爲」完成「。 哦,並且在執行LongMethod()期間UI被鎖定,因爲程序是單線程的。

我試過線程更早,但對我的生活我不能得到正確的語法,我想:

Thread MyThread = new Thread(LongClass.LongFunction); 

Thread MyThread = new Thread(new ThreadStart(LongClass.LongFunction)); 

哪裏LongClass是包含LongFunction作爲一個靜態方法的類。 我會檢查出現在的背景工作者。

+0

如果您在'LongMethod()'之前向'Application.DoEvents()'添加了一個調用,那麼您將使用臨時創可解決此問題。傑森的回答是正確的方法。 –

回答

6

您應該在另一個線程上執行LongMethod,以便UI線程在運行時不會阻塞。

+0

LongMethod是另一個類的靜態方法,我還可以在另一個線程上運行它嗎? – 7VoltCrayon

+0

@Suleman是的。通常,任何長時間運行的進程都不應該阻塞UI線程。相反,您可以讓LongMethod在另一個線程上運行;然後提出一個事件來通知UI它已完成。 – vcsjones

+1

'BackgroundWorker'使這個更容易一些。 –

3

雖然我認爲Jason的使用另一個線程的答案是要走的路,但還有另一個「evil」選項。

Statuslabel.Text = "Working..."; 

Application.DoEvents(); 

LongMethod(); 

Statuslabel.Text = "Done"; 
6

記住,更新UI是運行的代碼就像其他任何東西。當您的長時間運行的方法正在運行時,該線程沒有執行重繪用戶界面所需的任何任務。更改UI元素並不會阻止所有內容並重新繪製它,因爲假設您更改了一千個UI元素;你不會期望在每一個之後重繪;在你做出所有改變之後,你會希望他們都會立即發生。長話短說,如果你想刷新更新後的用戶界面,但在長時間運行的代碼之前 - 也就是說,你不關心掛用戶界面,但你至少希望它更新 - 然後插入一個明確刷新UI的調用。

有些人建議將「DoEvents」作爲解決方法。這可以工作,但它是超級危險。有兩個原因。首先,假設用戶點擊一次按鈕兩次。在第一次點擊的處理過程中,你做了一個DoEvents,然後你遞歸嘿,現在你已經暫停了第一個按鈕點擊的處理,以便你可以處理第二個按鈕的點擊......並且可以'不錯。其次,假設你正在處理一個事件,並且你做了一個DoEvents,它使你開始處理另一個事件,然後當你這樣做時,你做了一個DoEvents,並且這會導致你開始處理第三個事件...並且這一直持續下去。你什麼時候完成第一個事件?潛在的從來沒有。記住「DoEvents」基本上意思是「專注於剛剛發生的事情,犧牲了你已經在做的事情」。

+0

對於事實+1:DoEvents。我花了數週的時間修復由認爲DoEvents是神奇的治療方法的人編寫的代碼 - 這意味着他永遠不必費心研究線程是如何工作的。 (爲了記錄,有人不是我);)) –