C#使用Task在Winform建立控件上的提示等待窗口,实现局部等待加载,不影响主线程

  • C#使用Task在Winform建立控件上的提示等待窗口,实现局部等待加载,不影响主线程已关闭评论
  • 240 次浏览
  • A+
所属分类:.NET技术
摘要

效果图 用用户控件新建等待窗口    调用代码从调用方式可以看出仅仅只是父级和数据处理方法不同。可自行进行架构优化

效果图

 

用用户控件新建等待窗口

C#使用Task在Winform建立控件上的提示等待窗口,实现局部等待加载,不影响主线程

 C#使用Task在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
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任