在用.net framework框架的winform構建gui程式介面時,如果要在控制項的事件響應函式中改變控制項的狀態,例如:某個按鈕上的文字原先叫「開啟」,單擊之後按鈕上的文字顯示「關閉」,初學者往往會想當然地這麼寫:
void buttononclick(object sender,eventargs e)
這樣的寫法執行程式之後,可能會觸發異常,異常資訊大致是「不能從不是建立該控制項的執行緒呼叫它」。注意這裡是「可能」,並不一定會觸發該種異常。造成這種異常的原因在於,控制項是在主線程中建立的(比如this.controls.add(...);),進入控制項的事件響應函式時,是在控制項所在的執行緒,並不是主線程。在控制項的事件響應函式中改變控制項的狀態,可能與主線程發生執行緒衝突。如果主線程正在重繪控制項外觀,此時在別的執行緒改變控制項外觀,就會造成畫面混亂。不過這樣的情況並不總會發生,如果主線程此時在重繪別的控制項,就可能逃過一劫,這樣的寫法可以正常通過,沒有觸發異常。
正確的寫法是在控制項響應函式中呼叫控制項的invoke方法(其實如果大家以前用過c++ builder的話,也會找到類似invoke那樣的啟用到主線程的函式)。invoke方法會順著控制項樹向上搜尋,直到找到建立控制項的那個執行緒(通常是主線程),然後進入那個執行緒改變控制項的外觀,確保不發生執行緒衝突。正確寫法的示例如下:
void buttononclick(object sender,eventargs e)
));}
invoke方法需要建立乙個委託。你可以事先寫好函式和與之對應的委託。不過,若想直觀地在invoke方法呼叫的時候就看到具體的函式,而不是到別處搜尋的話,上面的示例**是不錯的選擇。
這樣的寫法有乙個煩人的地方:對不同的控制項寫法不同。對於textbox,要textboxobject.invoke,對於label,又要labelobject.invoke。有沒有統一一點的寫法呢?
主視窗類本身也有invoke方法。如果你不想對不同的控制項寫法不一樣,可以全部用this.invoke:
void buttononclick(object sender,eventargs e)
));}
在c# 3.0及以後的版本中有了lamda表示式,像上面這種匿名委託有了更簡潔的寫法。.net framework 3.5及以後版本更能用action封裝方法。例如以下寫法可以看上去非常簡潔:
void buttononclick(object sender,eventargs e)
));}
以上寫法往往充斥著winform構建的程式。
在微軟新一代的介面開發技術wpf中,由於介面呈現和業務邏輯原生態地分開在兩個執行緒中,所以控制項的事件響應函式就不必invoke了。但是,如果手動開闢乙個新執行緒,那麼在這個新執行緒中改變控制項的外觀,則還是要invoke的。
pythonpip使用方法 pip使用方法整理
匯出專案已安裝的pip包 pip list 檢視專案中安裝的包 pip freeze requirements.txt 將專案中所用到的第三方庫輸出到requirements.txt中 pip install 版本號 pip install i 本次使用清華源進行安裝 離線安裝第三方庫 一鍵安裝整個...
使用方法 離型劑使用方法
1 使用離型劑前必須確保模具乾淨,無粉塵 蠟垢 樹脂垢 油汙等殘留物質。可以使用專用的模具潔模劑進行清洗,不可用其他液體清洗,以免清洗不乾淨或損壞模具。另外,如果您的模具是新的,在清洗乾淨後,務必要對模具進行初步處理,用離型劑在模具表面噴 刷塗5 6次,之後方可正常投入生產。2 使用離型劑時,首先要...
使用方法 卡丁車輪胎使用方法
輪胎的使用方法很重要 卡丁車輪胎是卡丁車場日常執行中的主要易損件,但是輪胎的使用方法很重要。哪些情況下會縮短輪胎的使用壽命呢?一 跑道地面粗糙 有的跑道在鋪瀝青時,或者選錯了瀝青中石子的規格,或者碾壓得不夠平整,導致路面粗糙。有的跑道使用現成的水泥地,但表面粗糙或不平整。有的室內跑道,為了提高輪胎的...