2012-11-22 120 views
0

我正在通過this tutorial關於如何在後臺執行一些工作以及在這段代碼中我很困惑,爲什麼在調用ReadTheFile(filename)方法之前沒有顯示消息reading the file...爲什麼這個順序操作沒有被執行?

private void btnSelect_Click(object sender, EventArgs e) 
{ 
    OpenFileDialog ofd = new OpenFileDialog(); 
    ofd.CheckFileExists = true; 
    ofd.CheckPathExists = true; 

    if (ofd.ShowDialog() == DialogResult.OK) 
    { 
     lblResults.Text = " ... reading the file ..."; 
     FileReader1 fr = new FileReader1(); 
     int numLines = fr.ReadTheFile(ofd.FileName); 

     lblResults.Text = string.Format("We read {0} lines", numLines.ToString()); 
    } 
} 

作者通過下面的說明解釋它,但它並沒有真正接觸到我。

Worse, even though we set the label’s Text property before we call ReadTheFile, the message loop doesn’t get a chance to process that change, and update the text, before we go out to lunch in ReadTheFile.

這是什麼意思?這可以用簡單的術語來解釋嗎?

+0

與表單運行的線程有關。在讀取文件之前,用戶界面沒有機會重新繪製。 –

回答

2

更糟的是,儘管我們設置標籤的Text屬性我們稱之爲ReadTheFile之前,消息循環沒有得到一個機會來處理這種變化,並更新文本,我們ReadTheFile出去吃午飯了。

基本上你正在設置標籤的文字。但是,您然後開始執行可能需要幾秒鐘,幾分鐘,幾小時的「強化」任務。只要您繼續加載文件並讀取行數,窗口將不會更新。這是在後臺線程中完成的關鍵。讓主線程繼續繪製窗口並在後臺線程處理文件時處理UI內容。

我會繼續教程。一旦你到達開始創建和運行後臺工作的地方,你可能會遇到其中一個「啊哈」!時刻。 =)

您可能也有興趣閱讀一般的主題。

http://www.codeproject.com/Articles/26148/Beginners-Guide-to-Threading-in-NET-Part-1-of-n

http://www.techrepublic.com/article/a-beginners-guide-to-threading-in-c/1044970

1

您可以閱讀Application.DoEvents Method

當您運行Windows窗體時,它會創建新窗體,然後等待 以處理事件。每次表單處理事件時,它都會處理與該事件關聯的所有代碼。所有其他事件 在隊列中等待。在您的代碼處理事件時,您的應用程序 不響應。例如,如果另一個 窗口頂部被拖動,窗口不會重新繪製。

因此,在您的btnSelect_Click完成之前,您的表單不會重新繪製。


我編輯我的回答一句話,說一了最好不要用DoEvents明確,因爲這可能會導致相當怪異PROGRAMM行爲。 (根據J.Skeet的評論)。

你也可以閱讀Use of Application.DoEvents() at SO瞭解更多信息。有從MSDN張貼在該線程的提取物:

調用此方法會導致同時 所有等待窗口消息被處理的當前線程被暫停。如果消息導致觸發事件 ,則應用程序代碼的其他區域可能會執行 。這可能會導致您的應用程序出現難以調試的意外 行爲。如果執行操作或需要很長時間的計算,通常最好在新線程上執行這些操作。

+2

雖然你不應該*通常使用* Application.DoEvents' ... –

+0

@JonSkeet完全同意 – horgh