一直想要寫一點東西,把自己在工作中遇到的東西分享給大家沈自,無奈水平有限,每每想寫的時候忌怎,就感覺寫的東西太過浮淺酪夷,同樣的東西不如其它人寫的有水平,假若自己再寫出來可能會給其它人帶來困惑捶索,加上自己語言組織能力不行,就懶得寫了辅甥,由于這兩天在分析UI刷新的性能問題燎竖,而今天也終于分析出性能損耗點,按捺不住心中的高興夏块,因此就想在這里給大家分享一下方法。
Dispatcher Queue性能分析
我相信脐供,學(xué)習(xí)過WPF人都會知道不能直接通過其它線程訪問UI控件借跪,原因是由地Windows操作系統(tǒng)使用的單線程的掏愁,基于消息處理的用戶界面,一次只能有一個線程訪問用戶界面沦泌,與任何輪換線程的交互都必須通過Windows消息泵來封送辛掠。而其它線程要訪問怎么辦,那只能通過消息封送了,常用的代碼如Dispatcher.BeginInvoke或Dispatcher.Invoke船侧。封送到UI線程進(jìn)行處理厅各。在控件與后臺邏輯頻繁交互的項目中的,這樣的封送代碼可能是相當(dāng)?shù)亩喽犹粒鴮τ诮缑鏀?shù)據(jù)加載慢這樣的問題,一一去查這些封送代碼顯然是相當(dāng)?shù)牟滑F(xiàn)實遮怜,那怎么辦鸿市?
其實,在我們封送消息到UI線程時焰情,封送的消息會以FIFO逐一進(jìn)行處理,當(dāng)然其還是一個優(yōu)先級的概念需要理解合敦。對于這樣的一個隊列验游,我們可以跟蹤加載到隊列每個任務(wù)的開始及結(jié)束時間,即可知道性能耗費點耕蝉,便可再跟據(jù)相關(guān)代碼進(jìn)行進(jìn)一步的分析。
MSDN中關(guān)于DispatcherHooks的定義
Func | Description |
---|---|
DispatcherInactive | 在調(diào)度程序沒有要處理的其他操作時發(fā)生 |
OperationAborted | 中止操作時發(fā)生 |
OperationCompleted | 完成操作時發(fā)生 |
OperationPosted | 將操作發(fā)布到調(diào)度程序時發(fā)生 |
OperationPriorityChanged | 在更改操作的優(yōu)先級時發(fā)生 |
OperationStarted | 調(diào)用操作時發(fā)生 |
我們可以對Dispatcher.Hooks進(jìn)行上面這些事件的附加即可知道每個任務(wù)的進(jìn)度炒俱,詳細(xì)可研究Msdn。添加到Dispatcher Queue中的每個任務(wù)都用一個DispatcherOperation來表示推盛,這個類型有一個Name屬性,可以用來標(biāo)識具體是什么樣的任務(wù)耘成,由于這個屬性是internal類型的,所以獲取時需要進(jìn)行反射獲取撒会,代碼簡單如下:
PropertyInfo pro = typeof(DispatcherOperation).GetProperty("Name", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic);
打印出每個任務(wù)的Name屬性诵肛,就可以進(jìn)一步分析性能了。
由于添加到Dispatcher Queue中的任務(wù)是相當(dāng)?shù)亩嗾荩鏤I渲染蓄诽,Input事件等,可以把相關(guān)的任務(wù)都打印到txt中乙埃,然后搜索自己程序中的命名空間锯岖,即可找到自己程序添加相關(guān)任務(wù),使用NotePad++, 相當(dāng)好用米酬。
Ending!!!