2009-07-12 247 views

回答

17

Application.DoEvents通常用於確保在UI線程上執行一些長時間運行的操作時處理事件。

更好的解決方案是不這樣做。在需要更新用戶界面時,在單獨的線程上執行長時間運行的操作,編組到UI線程(使用Control.BeginInvoke/InvokeBackgroundWorker)。

Application.DoEvents介紹了再次入侵的可能性,這可能會導致很難理解的錯誤。

+0

Jon, 你說過要確保事件得到定期處理......哪些事件?在順序編程中,假設我們在表單上有一個按鈕。當用戶點擊時,例如表單的不透明度發生變化... 現在,除了按鈕的點擊,這裏有什麼樣的事件? – odiseh 2009-07-12 06:56:42

1

Imho你應該少一些從不使用它,因爲你可能會以非常意想不到的行爲結束。 剛生成的代碼沒問題。像你這樣的事情再次執行事件處理程序,你目前在,因爲用戶按下一個鍵兩次等等等等 如果你想刷新控件來顯示當前的過程中,你應該明確地調用.Update上的控制,而不是調用的Application.DoEvents。

2

Windows維護一個隊列以容納各種事件,如點擊,調整大小,關閉等。當控件響應某個事件時,所有其他事件都會在隊列中停滯。因此,如果您的應用程序花了很長時間來處理按鈕單擊,應用程序的其餘部分將凍結。因此,當您的應用程序在響應某個事件時正在進行一些繁重的處理時,它可能顯示無響應。儘管理想情況下應該以異步方式進行繁重處理以確保UI不會凍結,但一個快速簡單的解決方案是定期調用Application.DoEvents(),以允許將未決事件發送到您的應用程序。

對於良好的Windows應用程序,最終用戶不喜歡何時執行較大/重量級操作時任何形式的應用程序凍結。用戶總是希望應用程序以平穩和響應的方式運行,而不是凍結UI。但是,谷歌搜索後,我發現,Application.DoEvents()是不是在應用程序更頻繁地使用這樣反而這樣的活動,最好使用後臺工作線程執行長時間不結冰的窗戶正在運行的任務一個很好的做法。

您可以得到更好的主意,如果你看一下實際它。只需複製以下代碼並檢查應用程序是否加入了Application.DoEvents()。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     For i As Integer = 0 To 1000 
      System.Threading.Thread.Sleep(100) 
      ListBox1.Items.Add(i.ToString()) 
      Application.DoEvents() 
     Next 
    End Sub