日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
【C#】分享帶等待窗體的任務(wù)執(zhí)行器一枚

適用環(huán)境:.net 2.0+的Winform項(xiàng)目。

創(chuàng)新互聯(lián)公司專注于企業(yè)全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、民樂(lè)網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、商城網(wǎng)站開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為民樂(lè)等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。

先解釋一下我所謂的【帶等待窗體的任務(wù)執(zhí)行器】是個(gè)什么鬼,就是可以用該類執(zhí)行任意耗時(shí)方法(下文將把被執(zhí)行的方法稱為任務(wù)或任務(wù)方法),執(zhí)行期間會(huì)顯示一個(gè)模式等待窗體,讓用戶知道任務(wù)正在得到執(zhí)行,程序并沒(méi)有卡死。先看一下效果:

功能:

等待窗體可以使用執(zhí)行器自帶的默認(rèn)窗體(就上圖的樣子),嫌丑你也可以使用自己精心設(shè)計(jì)的窗體,甚至基于Devexpress、C1等第三方漂亮窗體打造也是完全可以的
在任務(wù)中可以更新等待窗體上的Label、ProgressBar之類的控件以提供進(jìn)度反饋。懶得反饋的話,就默認(rèn)“請(qǐng)稍候...”+Marquee式滾動(dòng)
如果任務(wù)允許被終止,用戶可以通過(guò)某些操作終止任務(wù)執(zhí)行(例如點(diǎn)擊上圖中的【取消】按鈕);如果不允許,你可以把取消按鈕隱藏了,或者在任務(wù)中不響應(yīng)用戶的終止請(qǐng)求就好
任務(wù)的執(zhí)行結(jié)果(包括ref/out參數(shù))、是否出現(xiàn)異常、是否被取消等情況都可以得到

原理:

調(diào)用任務(wù)所屬委托的BeginInvoke,讓任務(wù)在后臺(tái)線程執(zhí)行,隨即在UI線程(通常就是主線程)調(diào)用等待窗體的ShowDialog彈出模式窗體,讓用戶知道任務(wù)正在執(zhí)行的同時(shí)阻止用戶進(jìn)行其他操作。由于任務(wù)和等待窗體分別在不同的線程跑,所以等待窗體不會(huì)被卡住

任務(wù)執(zhí)行期間可以通過(guò)執(zhí)行器提供的一組屬性和方法操作等待窗體上的控件,這組屬性和方法內(nèi)部是通過(guò)調(diào)用等待窗體的Invoke或BeginInovke對(duì)控件進(jìn)行操作,實(shí)現(xiàn)跨線程訪問(wèn)控件
任務(wù)執(zhí)行期間用戶可以通過(guò)點(diǎn)擊等待窗體上的【取消】按鈕(如果你讓它顯示的話)或點(diǎn)擊右上角關(guān)閉按鈕發(fā)出終止任務(wù)的請(qǐng)求(等待窗體會(huì)攔截關(guān)閉操 作),其結(jié)果是執(zhí)行器的UserCancelling屬性會(huì)置為true,所以在任務(wù)中可以訪問(wèn)該屬性得知用戶是否請(qǐng)求了取消操作,如果你同意終止的話, 需設(shè)置執(zhí)行器的Cancelled=true,并隨即return出任務(wù)方法

任務(wù)執(zhí)行完后(無(wú)論成功、異常、取消)會(huì)自動(dòng)進(jìn)入異步回調(diào)方法,回調(diào)方法中會(huì)首先訪問(wèn)Cancelled獲知任務(wù)是否已取消,如果已取消,則直接 return出回調(diào)方法;如果未取消,則調(diào)用任務(wù)所屬委托的EndInvoke得到任務(wù)執(zhí)行結(jié)果或異常。最后不管取消與否,finally塊中會(huì)設(shè)置等待 窗體的DialogResult屬性,以確保關(guān)閉等待窗體

等待窗體關(guān)閉后,執(zhí)行器會(huì)繼續(xù)執(zhí)行ShowDialog后面的語(yǔ)句。如果任務(wù)已取消,則拋出特定異常報(bào)告調(diào)用者;如果任務(wù)存在異常,則拋出該異常;以上情況都不存在的話,返回任務(wù)結(jié)果

如述,功能簡(jiǎn)單,實(shí)現(xiàn)容易,我只是把這種需求通用化了一下,讓還沒(méi)有類似輪子的朋友可以拿去就用。另外還有個(gè)基于BackgroundWorker的實(shí)現(xiàn)方式,我可能會(huì)在下一篇文章分享。

先看一下大致的使用示例:

 
 
  1. //WaitUI就是執(zhí)行器 
  2. private void button1_Click(object sender, EventArgs es) 
  3.     //可檢測(cè)執(zhí)行器是否正在執(zhí)行另一個(gè)任務(wù)。其實(shí)基本不可能出現(xiàn)IsBusy=true,因?yàn)閳?zhí)行器工作時(shí),用戶做不了其它事 
  4.     //老實(shí)說(shuō)這個(gè)IsBusy要不要公開(kāi)我還糾結(jié)了一下,因?yàn)楣_(kāi)了沒(méi)什么用,但也沒(méi)什么壞處,因?yàn)閟etter是private的 
  5.     //Whatever~最后我還是選擇公開(kāi),可能~因?yàn)閻?ài)情 
  6.     //if (WaitUI.IsBusy) { return; } 
  7.  
  8.     try 
  9.     { 
  10.         //WaitUI.RunXXX方法用于執(zhí)行任務(wù) 
  11.         //該方法的返回值就是任務(wù)的返回值 
  12.         //任務(wù)拋出的異常會(huì)通過(guò)RunXXX方法拋出 
  13.  
  14.         //WaitUI.RunAction(Foo, 33, 66);                                      //執(zhí)行無(wú)返回值的方法 
  15.         int r = WaitUI.RunFunc(Foo, 33, 66);                                  //執(zhí)行有返回值的方法 
  16.         //object r = WaitUI.RunDelegate(new Func(Foo), 33, 66);//執(zhí)行委托 
  17.         //WaitUI.RunAction(new MyWaitForm(), Foo);//指定自定義等待窗體執(zhí)行任務(wù),幾個(gè)RunXXX方法都有可指定自定義窗體的重載 
  18.  
  19.         MessageBoxEx.Show("任務(wù)完成。" + r); 
  20.     } 
  21.     catch (WorkCancelledException)//任務(wù)被取消是通過(guò)拋出該異常來(lái)報(bào)告 
  22.     { 
  23.         MessageBoxEx.Show("任務(wù)已取消!"); 
  24.     } 
  25.     catch (Exception ex)//任務(wù)拋出的異常 
  26.     { 
  27.         MessageBoxEx.Show("任務(wù)出現(xiàn)異常!" + ex.Message); 
  28.     } 
  29.  
  30. //耗時(shí)任務(wù)。因?yàn)樵摲椒〞?huì)在后臺(tái)線程執(zhí)行,所以方法中不可以有訪問(wèn)控件的代碼 
  31. int Foo(int a, int b) 
  32.     //可以通過(guò)執(zhí)行器的一系列公開(kāi)屬性和方法間接操作等待窗體的UI元素 
  33.     WaitUI.CancelControlVisible = true;//設(shè)置取消任務(wù)的控件的可見(jiàn)性,即是否允許用戶取消任務(wù)(默認(rèn)是false:不可見(jiàn)) 
  34.     WaitUI.BarStyle = ProgressBarStyle.Continuous;//設(shè)置滾動(dòng)條樣式(默認(rèn)是Marquee:循環(huán)梭動(dòng)式) 
  35.     WaitUI.BarMaximum = 100;      //設(shè)置滾動(dòng)條值上限(默認(rèn)是100) 
  36.     WaitUI.BarMinimum = 0;        //設(shè)置滾動(dòng)條值下限(默認(rèn)是0) 
  37.     WaitUI.BarStep = 1;           //設(shè)置滾動(dòng)條步進(jìn)幅度(默認(rèn)是10) 
  38.     WaitUI.BarVisible = true;     //設(shè)置滾動(dòng)條是否可見(jiàn)(默認(rèn)是true:可見(jiàn)) 
  39.  
  40.     int i; 
  41.     for (i = a; i < b; i++) 
  42.     { 
  43.         if (WaitUI.UserCancelling)//響應(yīng)用戶的取消請(qǐng)求 
  44.         { 
  45.             WaitUI.Cancelled = true;//告訴執(zhí)行器任務(wù)已取消 
  46.             return 0; 
  47.         } 
  48.  
  49.         //可以拋個(gè)異常試試 
  50.         //if (i == 43) { throw new NotSupportedException("異常測(cè)試"); } 
  51.  
  52.         //可以隨時(shí)再次操作等待窗體的各種UI元素 
  53.         //if (i % 10 == 0) { WaitUI.CancelControlVisible = false; }   //隱藏取消控件 
  54.         //else if (i % 5 == 0) { WaitUI.CancelControlVisible = true; }//顯示取消控件 
  55.         WaitUI.WorkMessage = "正在XXOO,已完成 " + i + " 下..."; //更新進(jìn)度描述 
  56.         WaitUI.BarValue = i;//更新進(jìn)度值 
  57.         //WaitUI.BarPerformStep();//步進(jìn)進(jìn)度條 
  58.  
  59.         Thread.Sleep(100); 
  60.     } 
  61.     return i; 

看完示例,熟悉套路的你可能都已經(jīng)能洞悉實(shí)現(xiàn)細(xì)節(jié)了,不過(guò)作為方案分享文章,我還是照章講一下使用說(shuō)明先,后面再掰扯設(shè)計(jì)說(shuō)明,先看類圖:

使用說(shuō)明:

WaitUI通過(guò)RunAction、RunFunc、RunDelegate這3個(gè)基本方法和它們的重載執(zhí)行任務(wù),看名字就知道,它們依次是執(zhí)行無(wú)返回值方法、有返回值方法和自定義委托,每個(gè)方法都有不指定等待窗體和指定等待窗體兩種重載形態(tài),不指定時(shí)就使用方案自帶的WaitForm作為等待窗體。自定義等待窗體需實(shí)現(xiàn)IWaitForm接口,詳情在后面的設(shè)計(jì)說(shuō)明部分有說(shuō)。這 里就表示等待窗體是在執(zhí)行任務(wù)時(shí)才傳進(jìn)去的,任務(wù)執(zhí)行完成后,WaitUI會(huì)銷毀等待窗體,這是為了讓W(xué)aitUI作為一個(gè)靜態(tài)類,盡量短暫的持有對(duì)象, 節(jié)約內(nèi)存。所以如果傳入的是自定義等待窗體的變量,請(qǐng)注意不要在WaitRun之后再次使用該變量,因?yàn)樗呀?jīng)被銷毀,推薦的做法是直接在RunXXX中 new一個(gè)自定義等待窗體。當(dāng)然如果不嫌棄自帶等待窗體,直接就不用傳入,自然不會(huì)有這個(gè)問(wèn)題。前兩種方法是泛型方法,根據(jù)Action和Func這倆泛型委托重載,這倆委托支持到最多16個(gè)參數(shù),但為了節(jié)約篇幅,方案中只重載了0~8個(gè)參數(shù)的情況,用戶可以根據(jù)需要增加重載。它 倆可以執(zhí)行任意不多于8個(gè)參數(shù)的有返回或無(wú)返回方法,得益于編譯器的智能推斷,使用時(shí)非常方便,直接RunAction(Foo, arg1, arg2, ...)就好了,根本不用糾結(jié)到底要使用哪個(gè)重載。對(duì)于RunDelegate方法,接受的是一個(gè)委托實(shí)例,也就是不能直接傳入方法,必須要用委托把方法 套上才行。任何委托都可以傳入,所以RunDelegate是最應(yīng)萬(wàn)變的方法,當(dāng)你的方法存在ref/out參數(shù),或者參數(shù)個(gè)數(shù)變態(tài)到超過(guò)16個(gè)時(shí),你還 可以也只可以選用RunDelegate。但有個(gè)限制,委托有且只有綁定一個(gè)方法,RunXXX拒絕執(zhí)行委托鏈

RunFunc和RunDelegate方法有返回值,前者的返回類型與任務(wù)方法的返回類型一致,后者則是object。它倆的返回值就是任務(wù)方法的返回值。同樣,任務(wù)拋出的異常一樣會(huì)在3種RunXXX方法中拋出來(lái),等于用RunXXX執(zhí)行任務(wù)與直接調(diào)用任務(wù)相比,除了寫(xiě)法上有所不同:

 
 
  1. int a = WaitUI.RunFunc(Foo,33); 
  2. int b = Foo(33); 

調(diào)用體驗(yàn)是一樣一樣的,所以你拿去就可以用,不需要對(duì)任務(wù)方法做什么修改,帶個(gè)套就完事兒,除非任務(wù)方法存在下面這種情況

原理中說(shuō)過(guò),RunXXX方法實(shí)際上是調(diào)用任務(wù)所屬委托的BeginInvoke方法,也就是異步執(zhí)行任務(wù),也就是任務(wù)會(huì)在另一個(gè)線程執(zhí)行。所以任務(wù)中不能訪問(wèn)控件,這恐怕是該方案最大的不便,但確實(shí)原理所限,所以如果你的任務(wù)有訪問(wèn)控件的代碼,還得做出改動(dòng)才行。要問(wèn)為什么非得讓任務(wù)在后臺(tái),而等待窗體在前臺(tái),不可以調(diào)換過(guò)來(lái)嗎?那樣不就沒(méi)這個(gè)不便了嗎?那是因?yàn)榈却绑w如果不在主線程ShowDialog,它就達(dá)不到模式的效果,用戶仍然可以唱歌跳舞,這恐怕是你不愿意的

任務(wù)中可以通過(guò)WaitUI的一組屬性和方法(WorkMessage、BarValue、BarPerformStep等)更新等待窗體中的文 本呈現(xiàn)控件和進(jìn)度指示控件(不限于Label和ProgressBar,取決于等待窗體的設(shè)計(jì)),用來(lái)向用戶報(bào)告任務(wù)執(zhí)行進(jìn)度。當(dāng)然不想做任何報(bào)告也可 以,就讓用戶面對(duì)一個(gè)“請(qǐng)稍候...”和循環(huán)滾動(dòng)條也無(wú)不可,具體文字和滾動(dòng)條樣式取決于等待窗體的默認(rèn)設(shè)置

WaitUI有個(gè)CancelControlVisible屬性,可以設(shè)置為true/false控制等待窗體上是否顯示【取消】按鈕之類的控件 (不限于Button,取決于等待窗體的設(shè)計(jì),所以下文不說(shuō)取消按鈕,說(shuō)取消控件)。這里需要詳細(xì)說(shuō)一下該方案的取消任務(wù)的機(jī)制,其實(shí)與BackgroundWorker的機(jī)制一致(好吧是我借鑒了它),熟悉bgw的老鳥(niǎo)請(qǐng)略過(guò)。顯示取消控件只代表用戶可以請(qǐng)求終止任務(wù),至于你(或者說(shuō)任務(wù))是否響應(yīng)這 個(gè)請(qǐng)求(同意終止與否)是另一回事。什么意思,就是用戶點(diǎn)擊取消控件后,不是說(shuō)任務(wù)就會(huì)自動(dòng)終止了~憑什么會(huì)終止嘛對(duì)吧,任務(wù)在線程池,又不可能 Abort,所以任務(wù)是否終止完全取決你在任務(wù)代碼中的處理,比如你在任務(wù)中段就來(lái)個(gè)return或throw ex,這個(gè)就叫終止,任由代碼執(zhí)行下去,就叫做沒(méi)終止,所以用戶請(qǐng)求終止與任務(wù)是不是真的終止了沒(méi)有必然聯(lián)系。說(shuō)這么多是什么意思,就是如果你要讓用戶看 到取消控件,那么你就應(yīng)該響應(yīng)用戶的請(qǐng)求,反過(guò)來(lái)如果不想任務(wù)被終止,那么就別讓用戶有發(fā)起請(qǐng)求的可能,當(dāng)然這是與技術(shù)無(wú)關(guān)的純?nèi)藱C(jī)交互理念的東西,沒(méi)有 對(duì)錯(cuò),反正我是建議不要欺騙用戶,下面說(shuō)說(shuō)如何響應(yīng)終止請(qǐng)求。當(dāng)用戶發(fā)起終止請(qǐng)求后,WaitUI的UserCancelling會(huì)變?yōu)閠rue,在任務(wù) 中你可以根據(jù)這個(gè)值來(lái)做出終止任務(wù)的處理,但是在終止之前,還得麻煩你設(shè)置一個(gè)標(biāo)記,千萬(wàn)別忘記,就是讓W(xué)aitUI.Cancelled = true,這等于告訴執(zhí)行器任務(wù)確實(shí)終止了,在設(shè)置完標(biāo)記后,最好緊跟終止代碼,不要再做其它事,讓Cancelled與事實(shí)一致。執(zhí) 行器中根據(jù)Cancelled來(lái)獲知任務(wù)是否已終止,進(jìn)而做出相應(yīng)的處理和返回。為什么不根據(jù)UserCancelling而是Cancelled相信你 已經(jīng)明白了,前者是用戶的意愿,后者是開(kāi)發(fā)者的決定,當(dāng)然是決定靠譜?;氐紺ancelControlVisible屬性,這個(gè)屬性建議在任務(wù)方法頂部就 設(shè)置,因?yàn)橐粋€(gè)任務(wù)是否可終止應(yīng)該是確定的,通常來(lái)說(shuō),循環(huán)類任務(wù)是可以終止的,例如批量處理圖片,一圈處理一張,那這種任務(wù)是可以也應(yīng)該允許用戶終止 的;而非循環(huán)類任務(wù),或者原子性比較強(qiáng)的任務(wù),開(kāi)始了就只能等待結(jié)果或報(bào)錯(cuò),這種任務(wù)一方面可能就不允許用戶終止,另一方面則是想終止都終止不了(比如 WebRequest.GetResponse、SqlCommand.ExecuteNonQuery之類),這種任務(wù)最好就不提供取消控件給用戶。不 過(guò)CancelControlVisible也像WorkMessage之類的屬性一樣,是可以在任務(wù)中隨時(shí)+反復(fù)設(shè)置的,所以你的任務(wù)可能有些階段可被 終止,有時(shí)則不允許終止,開(kāi)開(kāi)合合都是可以的,as you wish
RunXXX有3種執(zhí)行結(jié)果:①成功執(zhí)行任務(wù),返回任務(wù)返回值~如果任務(wù)有返回值的話;②任務(wù)產(chǎn)生異常,RunXXX會(huì)原樣拋出該異常;③任務(wù)被終止,拋出WorkCancelledException異常(后面有關(guān)于為什么選擇拋異常這種方式的說(shuō)明)。你自行根據(jù)不同結(jié)果做相應(yīng)處理

對(duì)于有ref/out參數(shù)的任務(wù)方法,如果你想在任務(wù)執(zhí)行后取回,請(qǐng)注意要這樣:

 
 
  1. //正確 
  2. object[] prms = { a, b }; 
  3. WaitUI.RunDelegate(new Action(Foo), prms); 
  4. a = prms[0]; 
  5. b = prms[1]; 
  6.  
  7. //錯(cuò)誤 
  8. WaitUI.RunDelegate(new Action(Foo), a, b); 

 

即要先構(gòu)造好參數(shù)數(shù)組(哪怕只有1個(gè)參數(shù)),完了傳入數(shù)組,最后從數(shù)組中取出的元素才是被蹂躡過(guò)的。不能直接傳入單個(gè)參數(shù)變量,那樣你是不能通過(guò)該變量取回改動(dòng)過(guò)的值的,具體原因自己悟

方案源碼:

WaitUI.cs包含class WaitUI和3個(gè)異常類WaitFormNullException、WorkIsBusyException、WorkCancelledException

 
 
  1. using System; 
  2. using System.Reflection; 
  3. using System.Windows.Forms; 
  4.  
  5. namespace AhDung.WinForm 
  6.     ///  
  7.     /// 執(zhí)行任務(wù)并顯示等候窗體 
  8.     ///  
  9.     public static class WaitUI 
  10.     { 
  11.         static IWaitForm waitForm; //等待窗體 
  12.         static object result;      //任務(wù)返回結(jié)果 
  13.         static Exception exception;//任務(wù)執(zhí)行異常 
  14.  
  15.         static object[] parmsInput;        //調(diào)用者傳入的參數(shù) 
  16.         static ParameterInfo[] parmsMethod;//任務(wù)所需的參數(shù) 
  17.         static bool isCallBackCompleted;   //指示回調(diào)方法是否已執(zhí)行完畢 
  18.  
  19.         ///  
  20.         /// 指示用戶是否已請(qǐng)求取消任務(wù) 
  21.         ///  
  22.         public static bool UserCancelling 
  23.         { 
  24.             get; 
  25.             private set; 
  26.         } 
  27.  
  28.         ///  
  29.         /// 指示任務(wù)是否已取消 
  30.         ///  
  31.         public static bool Cancelled 
  32.         { 
  33.             private get; 
  34.             set; 
  35.         } 
  36.  
  37.         ///  
  38.         /// 指示任務(wù)是否正在執(zhí)行中 
  39.         ///  
  40.         public static bool IsBusy 
  41.         { 
  42.             get; 
  43.             private set; 
  44.         } 
  45.  
  46.         #region 一系列操作等候窗體UI的屬性/方法 
  47.  
  48.         ///  
  49.         /// 獲取或設(shè)置進(jìn)度描述 
  50.         ///  
  51.         public static string WorkMessage 
  52.         { 
  53.             get 
  54.             { 
  55.                 if (waitForm.InvokeRequired) 
  56.                 { 
  57.                     return waitForm.Invoke(new Func(() => waitForm.WorkMessage)) as string; 
  58.                 } 
  59.                 return waitForm.WorkMessage; 
  60.             } 
  61.             set 
  62.             { 
  63.                 if (waitForm == null) { return; } 
  64.  
  65.                 if (waitForm.InvokeRequired) 
  66.                 { 
  67.                     waitForm.BeginInvoke(new Action(() => waitForm.WorkMessage = value)); 
  68.                     return; 
  69.                 } 
  70.                 waitForm.WorkMessage = value; 
  71.             } 
  72.         } 
  73.  
  74.         ///  
  75.         /// 獲取或設(shè)置進(jìn)度條可見(jiàn)性 
  76.         ///  
  77.         public static bool BarVisible 
  78.         { 
  79.             get 
  80.             { 
  81.                 if (waitForm.InvokeRequired) 
  82.                 { 
  83.                     return Convert.ToBoolean(waitForm.Invoke(new Func(() => waitForm.BarVisible))); 
  84.                 } 
  85.                 return waitForm.BarVisible; 
  86.             } 
  87.             set 
  88.             { 
  89.                 if (waitForm == null) { return; } 
  90.  
  91.                 if (waitForm.InvokeRequired) 
  92.                 { 
  93.                     waitForm.BeginInvoke(new Action(() => waitForm.BarVisible = value)); 
  94.                     return; 
  95.                 } 
  96.                 waitForm.BarVisible = value; 
  97.             } 
  98.         } 
  99.  
  100.         ///  
  101.         /// 獲取或設(shè)置進(jìn)度條動(dòng)畫(huà)樣式 
  102.         ///  
  103.         public static ProgressBarStyle BarStyle 
  104.         { 
  105.             get 
  106.             { 
  107.                 if (waitForm.InvokeRequired) 
  108.                 { 
  109.                     return (ProgressBarStyle)(waitForm.Invoke(new Func(() => waitForm.BarStyle))); 
  110.                 } 
  111.                 return waitForm.BarStyle; 
  112.             } 
  113.             set 
  114.             { 
  115.                 if (waitForm == null) { return; } 
  116.  
  117.                 if (waitForm.InvokeRequired) 
  118.                 { 
  119.                     waitForm.BeginInvoke(new Action(() => waitForm.BarStyle = value)); 
  120.                     return; 
  121.                 } 
  122.                 waitForm.BarStyle = value; 
  123.             } 
  124.         } 
  125.  
  126.         ///  
  127.         /// 獲取或設(shè)置進(jìn)度值 
  128.         ///  
  129.         public static int BarValue 
  130.         { 
  131.             get 
  132.             { 
  133.                 if (waitForm.InvokeRequired) 
  134.                 { 
  135.                     return Convert.ToInt32(waitForm.Invoke(new Func(() => waitForm.BarValue))); 
  136.                 } 
  137.                 return waitForm.BarValue; 
  138.             } 
  139.             set 
  140.             { 
  141.                 if (waitForm == null) { return; } 
  142.  
  143.                 if (waitForm.InvokeRequired) 
  144.                 { 
  145.                     waitForm.BeginInvoke(new Action(() => waitForm.BarValue = value)); 
  146.                     return; 
  147.                 } 
  148.                 waitForm.BarValue = value; 
  149.             } 
  150.         } 
  151.  
  152.         ///  
  153.         /// 獲取或設(shè)置進(jìn)度條步進(jìn)值 
  154.         ///  
  155.         public static int BarStep 
  156.         { 
  157.             get 
  158.             { 
  159.                 if (waitForm.InvokeRequired) 
  160.                 { 
  161.                     return Convert.ToInt32(waitForm.Invoke(new Func(() => waitForm.BarStep))); 
  162.                 } 
  163.                 return waitForm.BarStep; 
  164.             } 
  165.             set 
  166.             { 
  167.                 if (waitForm == null) { return; } 
  168.  
  169.                 if (waitForm.InvokeRequired) 
  170.                 { 
  171.                     waitForm.BeginInvoke(new Action(() => waitForm.BarStep = value)); 
  172.                     return; 
  173.                 } 
  174.                 waitForm.BarStep = value; 
  175.             } 
  176.         } 
  177.  
  178.         ///  
  179.         /// 使進(jìn)度條步進(jìn) 
  180.         ///  
  181.         public static void BarPerformStep() 
  182.         { 
  183.             if (waitForm == null) { return; } 
  184.  
  185.             if (waitForm.InvokeRequired) 
  186.             { 
  187.                 waitForm.BeginInvoke(new Action(() => waitForm.BarPerformStep())); 
  188.                 return; 
  189.             } 
  190.             waitForm.BarPerformStep(); 
  191.         } 
  192.  
  193.         ///  
  194.         /// 獲取或設(shè)置進(jìn)度條上限值 
  195.         ///  
  196.         public static int BarMaximum 
  197.         { 
  198.             get 
  199.             { 
  200.                 if (waitForm.InvokeRequired) 
  201.                 { 
  202.                     return Convert.ToInt32(waitForm.Invoke(new Func(() => waitForm.BarMaximum))); 
  203.                 } 
  204.                 return waitForm.BarMaximum; 
  205.             } 
  206.             set 
  207.             { 
  208.                 if (waitForm == null) { return; } 
  209.  
  210.                 if (waitForm.InvokeRequired) 
  211.                 { 
  212.                     waitForm.BeginInvoke(new Action(() => waitForm.BarMaximum = value)); 
  213.                     return; 
  214.                 } 
  215.                 waitForm.BarMaximum = value; 
  216.             } 
  217.         } 
  218.  
  219.         ///  
  220.         /// 獲取或設(shè)置進(jìn)度條下限值 
  221.         ///  
  222.         public static int BarMinimum 
  223.         { 
  224.             get 
  225.             { 
  226.                 if (waitForm.InvokeRequired) 
  227.                 { 
  228.                     return Convert.ToInt32(waitForm.Invoke(new Func(() => waitForm.BarMinimum))); 
  229.                 } 
  230.                 return waitForm.BarMinimum; 
  231.             } 
  232.             set 
  233.             { 
  234.                 if (waitForm == null) { return; } 
  235.  
  236.                 if (waitForm.InvokeRequired) 
  237.                 { 
  238.                     waitForm.BeginInvoke(new Action(() => waitForm.BarMinimum = value)); 
  239.                     return; 
  240.                 } 
  241.                 waitForm.BarMinimum = value; 
  242.             } 
  243.         } 
  244.  
  245.         ///  
  246.         /// 獲取或設(shè)置取消任務(wù)的控件的可見(jiàn)性 
  247.         ///  
  248.         public static bool CancelControlVisible 
  249.         { 
  250.             get 
  251.             { 
  252.                 if (waitForm.InvokeRequired) 
  253.                 { 
  254.                     return Convert.ToBoolean(waitForm.Invoke(new Func(() => waitForm.CancelControlVisible))); 
  255.                 } 
  256.                 return waitForm.CancelControlVisible; 
  257.             } 
  258.             set 
  259.             { 
  260.                 if (waitForm == null) { return; } 
  261.  
  262.                 if (waitForm.InvokeRequired) 
  263.                 { 
  264.                     waitForm.BeginInvoke(new Action(() => waitForm.CancelControlVisible = value)); 
  265.                     return; 
  266.                 } 
  267.                 waitForm.CancelControlVisible = value; 
  268.             } 
  269.         } 
  270.  
  271.         #endregion 
  272.  
  273.         #region 公共方法:無(wú)返回值+默認(rèn)窗體 
  274.  
  275.         ///  
  276.         /// 執(zhí)行方法并顯示默認(rèn)等候窗體 
  277.         ///  
  278.         public static void RunAction(Action method) 
  279.         { 
  280.             RunDelegate(method); 
  281.         } 
  282.  
  283.         ///  
  284.         /// 執(zhí)行方法并顯示默認(rèn)等候窗體 
  285.         ///  
  286.         public static void RunAction(Action method, T arg) 
  287.         { 
  288.             RunDelegate(method, arg); 
  289.         } 
  290.  
  291.         ///  
  292.         /// 執(zhí)行方法并顯示默認(rèn)等候窗體 
  293.         ///  
  294.         public static void RunAction(Action method, T1 arg1, T2 arg2) 
  295.         { 
  296.             RunDelegate(method, arg1, arg2); 
  297.         } 
  298.  
  299.         ///  
  300.         /// 執(zhí)行方法并顯示默認(rèn)等候窗體 
  301.         ///  
  302.         public static void RunAction(Action method, T1 arg1, T2 arg2, T3 arg3) 
  303.         { 
  304.             RunDelegate(method, arg1, arg2, arg3); 
  305.         } 
  306.  
  307.         ///  
  308.         /// 執(zhí)行方法并顯示默認(rèn)等候窗體 
  309.         ///  
  310.         public static void RunAction(Action method, T1 arg1, T2 arg2, T3 arg3, T4 arg4) 
  311.         { 
  312.             RunDelegate(
    新聞標(biāo)題:【C#】分享帶等待窗體的任務(wù)執(zhí)行器一枚
    URL分享:http://www.dlmjj.cn/article/dpgpisd.html