国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【C#】帶等待窗體的BackgroundWorker

2019-11-17 02:26:38
字體:
來源:轉載
供稿:網友
【C#】帶等待窗體的BackgroundWorker

---------------201504170911更新---------------

更新內容:刪除bgwUI新增的Start方法,改為通過new修飾符+可選參數的方式同時覆蓋基類(BackgroundWorker)的RunWorkerAsync有參和無參倆方法。所以執行任務仍舊使用熟悉的RunWorkerAsync即可,忘掉蹩腳的Start。在此要感謝園友【新的開始】在評論中的指點,非常感謝!

---------------20150416原文(已更新)---------------

適用環境:.net 2.0+的Winform項目

這是上一篇【分享帶等待窗體的任務執行器一枚】的姊妹篇,建議先看看那篇文章了解一下相關背景。這里簡單介紹一下,兩個方案的共同目的都是在執行耗時任務時向用戶顯示一個模式窗體(我稱等待窗體),通過該窗體,任務可以向用戶報告執行進度,用戶也可以通過它干預任務的執行(也就是取消~如果任務允許被終止的話),等于就是在任務與用戶之間通過一個等待窗體來進行信息傳遞。這樣的需求應該是很常見的,注重用戶體驗的開發者都不可能讓用戶眼巴巴的面對一個卡死掉的界面,所以相信在類似場景中,大家都有各自的處理手段,例如異步執行任務,同時在業務窗體上弄個滾動條什么的,比如這樣:

這樣的手段有的猿友可能已經形成了很完善的通用方案,比我這個好上百倍都不止(在此也懇請路過老鳥不吝分享自己的或自己知道的現成好方案),有的猿友則可能還是具體情況具體處理,沒有一個通用方案,而我在做的,就是把我的方案分享出來,讓還沒有類似輪子的猿友拿去后,經過簡單處理就能實現效果,同時,也希望得到老鳥的指點,不斷完善。

上一篇分享的是一個叫做WaitUI的執行器,可以執行任何方法,使用簡單。而這一篇分享的是一個叫做BackgroundWorkerUI的東東(下文簡稱bgwUI),看名字就知道它是基于BackgroundWorker(下文可能簡稱bgw)組件實現的,所以如果你更習慣bgw的使用方式,這個適合你。先看一下使用效果:

功能:

  • 在bgwUI執行任務期間(DoWork事件)顯示一個等待窗體,任務執行完成后自動消失。任務執行完是指DoWork事件跑完,而不是RunWorkerCompleted事件完,也就是RunWorkerCompleted執行期間已經沒有等待窗體了
  • 等待窗體可以自定義,但須實現IWaitForm接口
  • 在DoWork事件中可以訪問一組bgwUI提供的屬性和方法更新等待窗體上的文本和進度,以及可以控制等待窗體上的【取消】按鈕是否可見。是的,更新控件不需要再用PRogressChanged事件,事實上等待窗體實例(一個IWaitForm實例)對調用者是隱藏的,你不能也不需要直接對它操作,一切通過bgwUI進行
  • 如果任務允許被終止,即bgw.WorkerSupportsCancellation為true,等待窗體會顯示【取消】按鈕,用戶可以通過點擊它發出終止任務的請求,你可以像老樣子一樣,在DoWork中訪問CancellationPending獲知該請求
  • 其余功能與bgw一致

使用示例:

private void button2_Click(object sender, EventArgs e){    //構造函數的另一個重載可傳入自定義等待窗體的實例    using (BackgroundWorkerUI bgwUI = new BackgroundWorkerUI(/*new MyWaitForm()*/))    {        bgwUI.WorkerSupportsCancellation = true;//允許取消任務        bgwUI.DoWork += bgwUI_DoWork;        //bgwUI.ProgressChanged += bgwUI_ProgressChanged;//雖然不需要,但仍可注冊ProgressChanged事件做其它事        bgwUI.RunWorkerCompleted += bgwUI_RunWorkerCompleted;//亦可注冊RunWorkerCompleted事件        bgwUI.RunWorkerAsync();    }}void bgwUI_DoWork(object sender, DoWorkEventArgs e){    BackgroundWorkerUI bgwUI = sender as BackgroundWorkerUI;    //可以通過bgwUI的一組公開屬性和方法更新等待窗體    //bgwUI.CancelControlVisible = true;//設置取消任務的控件的可見性,默認該屬性會根據WorkerSupportsCancellation設置,但仍可以自由設置    bgwUI.BarStyle = ProgressBarStyle.Continuous;//設置滾動條樣式(默認是Marquee:循環梭動式)    bgwUI.BarMaximum = 100;      //設置滾動條值上限(默認是100)    bgwUI.BarMinimum = 0;        //設置滾動條值下限(默認是0)    bgwUI.BarStep = 1;           //設置滾動條步進幅度(默認是10)    bgwUI.BarVisible = true;     //設置滾動條是否可見(默認是true:可見)    int i;    for (i = Convert.ToInt32(e.Argument); i <= 100; i++)    {        if (bgwUI.CancellationPending)//老樣子,訪問CancellationPending獲知用戶是否取消任務        {            e.Cancel = true;            return;        }        //更新等待窗體不需要調用ReportProgress(),也不需要WorkerReportsProgress支持        bgwUI.WorkMessage = i.ToString();//設置任務進度描述        bgwUI.BarValue = i;              //設置任務進度值        //CancelControlVisible可以反復設置,不受WorkerSupportsCancellation限制        //if (i % 10 == 0) { bgw.CancelControlVisible = false; }        //else if (i % 5 == 0) { bgw.CancelControlVisible = true; }        Thread.Sleep(50);    }    e.Result = i;}void bgwUI_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){    if (e.Cancelled)    {        MessageBox.Show("任務已取消!");    }    else if (e.Error != null)    {        MessageBox.Show("任務有異常!" + e.Error.Message);    }    else    {        MessageBox.Show("任務完成。" + e.Result);    }}
使用示例

與BackgroundWorker的用法區別:

這里只講區別,沒講到的表示與bgw一致,不熟悉bgw用法的猿友請MSDN。先看類圖:

從類圖可看出bgwUI是繼承于bgw的子類。

  • bgwUI重載了一個可傳入IWaitForm實例的構造函數,就是可以傳入自定義等待窗體,使用無參構造函數的話,就使用默認的等待窗體,即WaitForm
  • DoWork事件中可以直接使用bgwUI的一組屬性和方法(WorkMessage、BarValue、BarPerformStep等)更新等待窗體,不再需要注冊ProgressChanged事件,完了在DoWork中bgw.ReportProgress,并且連WorkerReportsProgress屬性都不需要置為true。但是雖然更新等待窗體不需要ProgressChanged事件,但如果你仍然需要該事件做一些其它事,仍然可以注冊并照常使用

方案源碼

BackgroundWorkerUI.cs僅包含classBackgroundWorkerUI,它用到的WaitForm.cs請到上一篇文章取用,幫園子節約點空間~哈。

using System;using System.ComponentModel;using System.Windows.Forms;namespace AhDung.WinForm{    /// <summary>    /// 帶等待窗體的BackgroundWorker。報告進度用一組UI操作方法    /// </summary>    public class BackgroundWorkerUI : BackgroundWorker    {        readonly IWaitForm waitForm;//等待窗體        Form activeForm;//等待窗體顯示前的活動窗體        bool formClosed;//指示等待窗體是否已被關閉        #region 一組操作等候窗體UI的屬性/方法        /// <summary>        /// 獲取或設置進度描述        /// </summary>        public string WorkMessage        {            get            {                if (waitForm.InvokeRequired)                {                    return waitForm.Invoke(new Func<string>(() => waitForm.WorkMessage)) as string;                }                return waitForm.WorkMessage;            }            set            {                if (waitForm.InvokeRequired)                {                    waitForm.BeginInvoke(new Action(() => waitForm.WorkMessage = value));                    return;                }                waitForm.WorkMessage = value;            }        }        /// <summary>        /// 獲取或設置進度條可見性        /// </summary>        public bool BarVisible        {            get            {                if (waitForm.InvokeRequired)                {                    return Convert.ToBoolean(waitForm.Invoke(new Func<bool>(() => waitForm.BarVisible)));                }                return waitForm.BarVisible;            }            set            {                if (waitForm.InvokeRequired)                {                    waitForm.BeginInvoke(new Action(() => waitForm.BarVisible = value));                    return;                }                waitForm.BarVisible = value;            }        }        /// <summary>        /// 獲取或設置進度條動畫樣式        /// </summary>        public ProgressBarStyle BarStyle        {            get            {                if (waitForm.InvokeRequired)                {                    return (ProgressBarStyle)(waitForm.Invoke(new Func<ProgressBarStyle>(() => waitForm.BarStyle)));                }                return waitForm.BarStyle;            }            set            {                if (waitForm.InvokeRequired)                {                    waitForm.BeginInvoke(new Action(() => waitForm.BarStyle = value));                    return;                }                waitForm.BarStyle = value;            }        }        /// <summary>        /// 獲取或設置進度值        /// </summary>        public int BarValue        {            get            {                if (waitForm.InvokeRequired)                {                    return Convert.ToInt32(waitForm.Invoke(new Func<int>(() => waitForm.BarValue)));                }                return waitForm.BarValue;            }            set            {                if (waitForm.InvokeRequired)                {                    waitForm.BeginInvoke(new Action(() => waitForm.BarValue = value));                    return;                }                waitForm.BarValue = value;
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 延寿县| 内江市| 基隆市| 赤水市| 岳阳县| 潜山县| 井研县| 鹿泉市| 攀枝花市| 石屏县| 江城| 响水县| 武隆县| 芜湖市| 南郑县| 和硕县| 泽州县| 登封市| 赣榆县| 安化县| 长宁区| 巴彦淖尔市| 容城县| 景泰县| 兴义市| 女性| 南充市| 石楼县| 辽源市| 石城县| 那坡县| 东乌| 敖汉旗| 嘉禾县| 二手房| 乌鲁木齐县| 陕西省| 土默特右旗| 安化县| 克东县| 乌兰察布市|