需求:在開發過程中經常需要部分數據等待的載入。可能因為某個表比較慢而卡到主線程,所以需要實現局部載入等待。(在Web肯定就ajax非同步就好做,winform就比較複雜點了) 效果圖 效果圖的主要效果沒展示出來,就這樣吧。懶了懶了! 用用戶控制項新建等待視窗 //Loding2的類 public par ...
需求:在開發過程中經常需要部分數據等待的載入。可能因為某個表比較慢而卡到主線程,所以需要實現局部載入等待。(在Web肯定就ajax非同步就好做,winform就比較複雜點了)
效果圖
效果圖的主要效果沒展示出來,就這樣吧。懶了懶了!
用用戶控制項新建等待視窗
//Loding2的類 public partial class Loading2 : UserControl, IDisposable//繼承IDisposable { Timer timer1 = new Timer(); public Loading2(Control contorl) { InitializeComponent(); this.Parent = contorl; this.Parent.Enabled = false; this.Visible = false;//預設不顯示
timer1=new System.Windows.Forms.Timer(this.components);
timer1.Interval=30000;
timer1.Tick+=new System.EventHandler(this.timer1_Tick);
} public void Close() { //自寫Close方法釋放資源 this.Dispose(); }
//開始運行計時以及顯示 public void Start() { this.SendToBack(); this.Visible = true;//顯示 timer1.Enabled = true;//開始計時 } private void Loading2_Layout(object sender, LayoutEventArgs e) { ReLocation();//繪製位置到父級控制項中間 } private void ReLocation() { int x = (int)(0.5 * (Parent.Width - this.Width)); int y = (int)(0.5 * (Parent.Height - this.Height)); this.Location = new System.Drawing.Point(x, y); } private void timer1_Tick(object sender, EventArgs e) { LogHelper.Instance.Error("載入超時!");
timer1.Stop();//手動停止,不然就算用戶控制項Dispose了,timer也不會釋放和停止 Close();//超時關閉 } /// <summary> /// 使用new關鍵字覆蓋原有System.Windows.Forms的Dispose /// </summary> private new void Dispose() { if (this.InvokeRequired)//線上程中調用,使用Invoke執行是否該用戶控制項代碼 { this.Invoke(new Action(() => { if (this.Parent != null) { this.Parent.Enabled = true;//啟用父控制項 } Dispose(true);timer1.Dispose();//timer1是非托管資源需手動結束回收,避免任務過多導致記憶體問題程式奔潰 })); } else { if (this.Parent != null) { this.Parent.Enabled = true; } Dispose(true);timer1.Dispose(); } } }
調用代碼
Task<Loading2> task = null; CancellationTokenSource cancelTokenSource = null; private void LoadList() { //當上一個任務還在執行時候,最新任務到來。則取消上個任務 if (task != null) { cancelTokenSource.Cancel(); task = null; } cancelTokenSource = new CancellationTokenSource(); Loading2 w = new Loading2(uiGroupBox1); //這裡設置了載入的Loading父級是uigroupbox w.Start(); task = Task.Factory.StartNew(() => { LoadListData();//處理數據,裡面對控制項的操作需非同步處理 return w; }, cancelTokenSource.Token); //ContinueWith添加延續任務 task.ContinueWith(task => { task.Result.Close();//無論異常/取消/完成 都執行關閉 if (task.IsCanceled) { //取消後執行的代碼 } if (task.IsCompleted) { //完成後執行的代碼 } if (task.IsFaulted) { //報錯執行的代碼 } },TaskContinuationOptions.AttachedToParent);//,TaskContinuationOptions標明後續任務創建方式或者和task的關係。AttachedToParent表示當前延續任務為task的子任務 }
從調用方式可以看出僅僅只是父級和數據處理方法不同。可自行進行架構優化
作者:兮去博客
出處:https://www.cnblogs.com/bklsj/p/16784749.html
版權:本文版權歸作者和博客園共有
轉載:歡迎轉載,但未經作者同意,必須保留此段聲明;必須在文章中給出原文連接;否則必究法律責任