System.Windows.Forms.Application.DoEvents();


關於Application.DoEvents()的小研究

在MSDN中的備注是:

當運行 Windows 窗體時,它將創建新窗體,然后該窗體等待處理事件。該窗體在每次處理事件時,均將處理與該事件關聯的所有代碼。所有其他事件在隊列中等待。在代碼處理事件時,應用程序並不響應。例如,當將另一窗口拖到該窗口前面時,該窗口不重新繪制。

 

如果在代碼中調用 DoEvents,則您的應用程序可以處理其他事件。例如,如果您有向 ListBox 添加數據的窗體,並將 DoEvents 添加到代碼中,那么當將另一窗口拖到您的窗體上時,該窗體將重新繪制。如果從代碼中移除 DoEvents,那么在按鈕的單擊事件處理程序執行結束以前,您的窗體不會重新繪制。

 

剛開始接觸這段話的時候,會讀不懂。所以我就去找了篇文章,文章中通過一個循環輸出文本的例子解釋了通過這段代碼可以給人帶來很好的用戶體驗( 不加的話程序只會顯示輸出循環最后的結果,但是加了以后會實時的輸出),從而消除了認為進程死掉的情況。他還提到了用這個的缺點是影響了進程的效率,並通過了一個測驗證實他的觀點。

 

看了他的博客,我也就仿照他的說明寫了個代碼進行了測驗,第一個代碼是同他說的一樣,加不加代碼的效果是不同的。但是第二個,因為用一個計時器來計時。我因為不是很懂計時器,我就寫了個類似計時器的代碼,原理感覺上和他的差不多。

原理是:用Timer組件,寫了一個Tick事件並設置了間隔時間,在事件內用了一個counter 來計數,再通過計數的結果已經響應的時間間隔來計算時間。再運行加了DoEvents代碼的運行的很好,和我想的一樣。

  運行后發現,textBox2.可以得到99999就是結果的值,但是 label2卻一直是零,也就相當於沒有觸發Tick事件,這就把給搞昏了,我明明是設定了Timer的Start而且也在循環之前調用的Tick 事件,這是為什么呢?我又試着將代碼里的stop 給注釋掉,再運行,在循環結束后可以運行Tick 事件了。從這個結果來看,開始以為Tick本來是可以運行的。因為Tick的觸發是在當指定的計時器間隔已過去而且計時器處於啟用狀態時發生。那么有可能時間間隔太長,導致時間間隔沒解釋,也就是Tick來不及觸發。為了驗證這個是否正確,我將時間間隔調小,但是結果還是那樣,而且到后來我直接將Tick的事件觸發代碼帶到了循環中,可結果還是那樣。到此,我想也許是存在優先級的概念,是否循環這個進程的優先級比Tick的優先級高。之前在循環體內設置的到99999后的Stop掉Timer,直接導致Tick剛要執行就被強行關掉了。因為MSDN上也查不到這方面的原因,我就此當做是結論了。

     

      從這個測驗后再回頭想DoEvents的功能,我就想DoEvents就好比實現了進程的同步。在不加的時候,因為優先級的問題,程序會執行主進程的代碼,再執行Tick的代碼,而加了以后就可以同步執行。

從這個測驗后再回頭想DoEvents的功能,我就想DoEvents就好比實現了進程的同步。在不加的時候,因為優先級的問題,程序會執行主進程的代碼,再執行Tick的代碼,而加了以后就可以同步執行。

 

再回想那位網友在博客里寫到的:

http://www.cnblogs.com/datong/archive/2008/04/06/1139216.html


 

關於Application.DoEvents()

記得第一次使用Application.DoEvents()是為了在加載大量數據時能夠有一個數據加載的提示,不至於系統出現假死的現象,當時也沒有深入的去研究他的原理是怎樣的,結果在很多地方都用上了Application.DoEvents(),今天看到了關於這方面的一些文章,知道我以前有些用法是不當的,有些地方需要慎用Application.DoEvents()。
首先我們先看看在循環比較大的程序中,它的作用還是不錯的,起到了一個實時響應的效果,例如:

                        for (int q = 0; q < 1000000; q++)
            {
                textBox1.Text = q.ToString();
                Application.DoEvents();//實時響應文本框中的值
            }

如果沒有加上 DoEvents的話,由於循環時間會比較久就會出現假死的狀態,而且程序不能處理其他的事件。而如果加上DoEvents的話就會對文本框的值實時響應,給用戶帶來較好的用戶體驗,可是DoEvents也帶來了效率上的問題,處理同樣的一個事件調用了DoEvents后效率降低了好幾倍,這也是為什么要慎用的原因了。

 


      現在來分析的話,就可以解釋為什么,加了這行代碼后。程序就會出實現類似雙線程的功能,他會去尋找是否有別的事件,因為有這段時間才使得數值有時間可以顯現。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM