C#——界面防卡Application.DoEvents()
是什么
初識Application.DoEvents()是看托管D3D代碼。一般winform的Main函數是這樣的:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
大家知道Application.Run方法是在當前線程上開始運行標準應用程序消息循環。有時候我們需要實時的更新數據,比如D3D游戲要實現一個游戲主循環,比較好的做法就是自己構造這個循環。請看代碼:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var frm = new Form1();
frm.Show();
while (frm.Created)
{
Application.DoEvents();
// DoUpdate();
Thread.Sleep(16);
}
}
運行上述代碼,和第一份代碼的效果一樣,Application.DoEvents()會處理掉所有winform消息,比如鼠標鍵盤事件,界面刷新等。DoUpdate()函數會在每次界面更新的時候執行,而且幾乎沒什么特別的性能開銷。
怎么用
那一般的winform程序不用實現游戲主循環,又有什么用呢。還是直接上代碼:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 1000000000; i++)
{
this.Text = i.ToString();
}
}
運行上面的代碼,窗口一定會卡死,因為UI線程一旦進入了這個函數就無法處理鼠標鍵盤事件了。接下來到Application.DoEvents()登場了:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 1000000000; i++)
{
this.Text = i.ToString();
Application.DoEvents();
}
}
即使點擊了按鈕,UI線程進入了這個函數,Application.DoEvents()可以將UI線程的使用權交給其他函數,鼠標鍵盤事件能被正常響應,界面自然不會卡了。
有什么坑
凡人用Application.DoEvents()一定是為了解決界面卡頓的問題。界面卡頓說明UI線程的時間被耗時的任務占用了,一個任務耗時無非兩種情況:1、受設備IO限制;2、受CPU計算能力限制。前者的正統解決方案是異步,后者的正統解決方案是并行。所以用Application.DoEvents()只有一個目的,偷懶。
我也偷了個懶,今天同事用async/awit的方式查詢數據庫,將數據綁定到DataGridView時拋了個“線程間操作無效”的異常。awit使用的線程是由SynchronizationContext.Current決定的,一步一步追根溯源,發現Application.DoEvents()執行后SynchronizationContext.Current屬性被覆蓋了。去掉所有Application.DoEvents(),問題解決,寫篇文章做個記錄。
轉:https://blog.csdn.net/qq_32069969/article/details/88319152?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control&dist_request_id=98256cfc-d836-48a1-8a70-b461fbb2ce23&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control
如果沒有加上 DoEvents的話,由于循環時間會比較久就會出現假死的狀態,而且程序不能處理其他的事件。而如果加上DoEvents的話就會對文本框的值實時響應,給用戶帶來較好的用戶體驗,可是DoEvents也帶來了效率上的問題,處理同樣的一個事件調用了DoEvents后效率降低了好幾倍,這也是為什么要慎用的原因了。
總結
以上是生活随笔為你收集整理的C#——界面防卡Application.DoEvents()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中BigInteger的各种方法
- 下一篇: *PAT_B_1024_Java(20分