C#--耗時(shí)操作實(shí)現(xiàn)UI界面實(shí)時(shí)更新不阻塞(耗時(shí)操作解決窗體卡頓)
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
前言C#實(shí)現(xiàn)窗體加載進(jìn)度條或者百分比實(shí)時(shí)顯示耗時(shí)操作的進(jìn)度,方法有很多。但是經(jīng)過我的學(xué)習(xí)、查找與實(shí)際應(yīng)用,發(fā)現(xiàn)Task配合MethodInvoker最為高效便捷。下面我就來(lái)結(jié)合代碼講一下要注意的問題。 基礎(chǔ)知識(shí)C#在winform上進(jìn)行耗時(shí)操作往往會(huì)放置progressbar,問題是在UI線程上進(jìn)行耗時(shí)操作就會(huì)導(dǎo)致UI線程阻塞,界面就會(huì)卡頓。所以勢(shì)必要另開一個(gè)線程進(jìn)行耗時(shí)操作,之后將耗時(shí)操作的過程實(shí)時(shí)反饋給UI線程即可,可問題是新開的線程向UI線程傳遞數(shù)據(jù)的時(shí)候,就會(huì)出現(xiàn)經(jīng)典報(bào)錯(cuò): InvalidOperationException,并提示消息:“從不是創(chuàng)建控件的線程訪問它。 這是因?yàn)镹ET原則上禁止跨線程訪問。因?yàn)檫@樣可能造成錯(cuò)誤的發(fā)生,有一種簡(jiǎn)單粗暴的方法是禁止編譯器對(duì)跨線程訪問作檢查,Control.CheckForIllegalCrossThreadCalls = false;可以實(shí)現(xiàn)訪問,但是什么時(shí)候出錯(cuò)不敢保證。 TaskTask是一個(gè)升級(jí)版本的Thread的類,它非常的靈活,支持取消、阻塞等待、合并、多個(gè)Task協(xié)同操作......??傊褂肨ask編碼高效易懂,你基本不用去研究Thread與ThreadPool了,雖然本質(zhì)上還是這個(gè)。我個(gè)人理解Task就是對(duì)Thread的再次封裝。 MethodInvokerMethodInvoker 是位于System.Windows.Forms下的元數(shù)據(jù),表示一個(gè)委托,該委托可以執(zhí)行托管代碼中聲明為void且不接受任何參數(shù)的任何方法。在對(duì)控件的 invoke 方法進(jìn)行調(diào)用時(shí)或需要一個(gè)簡(jiǎn)單委托又不想自己定義時(shí)可以使用該委托。 我是這樣理解的,在新線程中使用 MethodInvoker 委托執(zhí)行耗時(shí)操作, 其實(shí)相當(dāng)于是在主線程中執(zhí)行的,這樣就避免了跨線程訪問控件。 示例代碼
線程的延續(xù)采用ContinueWith解決 BeginInvoke解決界面的刷新問題 TaskScheduler.FromCurrentSynchronizationContext() 解決跨線程訪問報(bào)錯(cuò)
button2的方式可以在task線程中按順序執(zhí)行耗時(shí)操作。 該文章在 2024/11/27 18:53:32 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |