下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第在WPF中使用多線程更新UI有經(jīng)驗(yàn)的程序員們都知道:不能在UI線程上進(jìn)行耗時(shí)操作,那樣會(huì)造成界面卡頓,如下就是一個(gè)簡(jiǎn)單的示例:
publicpartialclassMainWindow:Window
publicMainWindow()
InitializeComponent();
this.Dispatcher.Invoke(newAction(()={}));
this.Loaded+=MainWindow_Loaded;
privatevoidMainWindow_Loaded(objectsender,RoutedEventArgse)
this.Content=newUserControl1();
classUserControl1:UserControl
TextBlocktextBlock;
publicUserControl1()
textBlock=newTextBlock();
this.Content=textBlock;
this.Dispatcher.BeginInvoke(newAction(updateTime),null);
privateasyncvoidupdateTime()
while(true)
Thread.Sleep(900);//模擬耗時(shí)操作
textBlock.Text=DateTime.Now.ToString();
awaitTask.Delay(100);
}
當(dāng)我們運(yùn)行這個(gè)程序的時(shí)候,就會(huì)發(fā)現(xiàn):由于主線程大部分的時(shí)間片被占用,無法及時(shí)處理系統(tǒng)事件(如鼠標(biāo),鍵盤等輸入),導(dǎo)致程序變得非常卡頓,連拖動(dòng)窗口都變得不流暢;
如何解決這個(gè)問題呢,初學(xué)者可能想到的第一個(gè)方法就是新啟一個(gè)線程,在線程中執(zhí)行更新:
publicUserControl1()
textBlock=newTextBlock();
this.Content=textBlock;
ThreadPool.QueueUserWorkItem(_=updateTime());
}
但很快就會(huì)發(fā)現(xiàn)此路不通,因?yàn)閃PF不允許跨線程訪問程序,此時(shí)我們會(huì)得到一個(gè):Thecallingthreadcannotaccessthisobjectbecauseadifferentthreadownsit.的InvalidOperationException異常
那么該如何解決這一問題呢?通常的做法是把耗時(shí)的函數(shù)放在線程池執(zhí)行,然后切回主線程更新UI顯示。前面的updateTime函數(shù)改寫如下:
privateasyncvoidupdateTime()
while(true)
awaitTask.Run(()=Thread.Sleep(900));
textBlock.Text=DateTime.Now.ToString();
awaitTask.Delay(100);
}
這種方式能滿足我們的大部分需求。但是,有的操作是比較耗時(shí)間的。例如,在多窗口實(shí)時(shí)監(jiān)控的時(shí)候,我們就需要同時(shí)多十來個(gè)屏幕每秒鐘各進(jìn)行幾十次的刷新,更新圖像這個(gè)操作必須在UI線程上進(jìn)行,并且它有非常耗時(shí)間,此時(shí)又會(huì)回到最開始的卡頓的情況。
看起來這個(gè)問題無法解決,實(shí)際上,WPF只是不允許跨線程訪問程序,并非不允許多線程更新界面。我們大可以對(duì)每個(gè)視頻監(jiān)控窗口單獨(dú)其一個(gè)獨(dú)立的線程,在那個(gè)線程中進(jìn)行更新操作,此時(shí)就不會(huì)影響到主線程。MSDN上有篇文章介紹了詳細(xì)的操作:MultithreadedUI:HostVisual。用這種方式將原來的程序改寫如下:
privatevoidMainWindow_Loaded(objectsender,RoutedEventArgse)
HostVisualhostVisual=newHostVisual();
UIElementcontent=newVisualHost(hostVisual);
this.Content=content;
Threadthread=newThread(newThreadStart(()=
VisualTargetvisualTarget=newVisualTarget(hostVisual);
varcontrol=newUserControl1();
control.Arrange(newRect(newPoint(),content.RenderSize));
visualTarget.RootVisual=control;
System.Windows.Threading.Dispatcher.Run();
}));
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground=true;
thread.Start();
publicclassVisualHost:FrameworkElement
Visualchild;
publicVisualHost(Visualchild)
if(child==null)
thrownewArgumentException("child");
this.child=child;
AddVisualChild(child);
protectedoverrideVisualGetVisualChild(intindex)
return(index==0)child:null;
protectedoverrideintVisualChildrenCount
get{return1;}
}
這個(gè)里面用來了兩個(gè)新的類:HostVisual、VisualTarget。以及自己寫的一個(gè)VisualHost。MSDN上相關(guān)的解釋,也不算難理解,這里就不多介紹了。最后,再來重構(gòu)一下代碼,把在新線程中創(chuàng)建控件的方式改寫如下:
privatevoidMainWindow_Loaded(objectsender,RoutedEventArgse)
createChildInNewThreadUserControl1(this);
voidcreateChildInNewThreadT(ContentControlcontainer)
whereT:UIElement,new()
HostVisualhostVisual=newHostVisual();
UIElementcontent=newVisualHost(hostVisual);
container.Content=content;
Threadthread=newThread(newThreadStart(()=
VisualTargetvisualTarget=newVisualTarget(hostVisual);
varcontrol=newT();
control.Arrange(newRect(newPoint(),content.RenderSize));
visualTarget.RootVisual=control;
System.Windows.Threading.Dispatcher.Run();
}));
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 中學(xué)學(xué)生宿舍用電管理制度
- 養(yǎng)老院工作人員交接班制度
- 企業(yè)內(nèi)部報(bào)銷與報(bào)銷審批制度
- 公共交通車輛維修保養(yǎng)制度
- 2026年企業(yè)內(nèi)部培訓(xùn)課程團(tuán)隊(duì)協(xié)作與領(lǐng)導(dǎo)力發(fā)展能力測(cè)試題
- 2026年計(jì)算機(jī)編程基礎(chǔ)Python語言編程練習(xí)題
- 2026年餐飲行業(yè)服務(wù)管理筆試模擬題
- 2026年醫(yī)藥物流項(xiàng)目管理與操作手冊(cè)及習(xí)題
- 2026年醫(yī)院網(wǎng)絡(luò)安全管理制度與實(shí)踐試題
- 2026年廚房設(shè)備以舊換新協(xié)議
- 場(chǎng)內(nèi)現(xiàn)場(chǎng)制售食品安全培訓(xùn)
- 《電滲析與電除鹽》課件
- 施工合作協(xié)議書范文范本電子版下載
- 煙草物理檢驗(yàn)競(jìng)賽考試題庫及答案
- 人才技術(shù)入股公司股權(quán)分配協(xié)議書
- 招聘會(huì)會(huì)展服務(wù)投標(biāo)方案(技術(shù)標(biāo) )
- 高考英語3500單詞表(帶音標(biāo))(亂序版)默寫背誦通用版
- 馬超-水田省力化劑型的開發(fā)及應(yīng)用研究-
- 頭面部的神經(jīng)阻滯課件
- 友達(dá)光電(昆山)有限公司第一階段建設(shè)項(xiàng)目環(huán)?!叭瑫r(shí)”執(zhí)行情況報(bào)告
- 光學(xué)下擺拋光技術(shù)培訓(xùn)教材
評(píng)論
0/150
提交評(píng)論