C# 异步汇报任务

1.通过Task实现: 

 

 1  private async void button4_Click(object sender, EventArgs e)
 2  {
 3      button4.Enabled = false;
 4      //此处不能用
 5      //Dojob().Wait();
 6 
 7      await Dojob();
 8      button4.Enabled = true;
 9   
10  }
11 
12  private async Task Dojob()
13  {
14      for (int i = 0; i <= 100; i++)
15      {
16          //ConfigureAwait(true)的作用是执行完await的任务后线程需要回到主线程,上面的wait会阻塞主线程,所以会产生死锁的现像,
17          //如果改为false ,是不会产生死锁,但下面的UI的操作会不在主线程,变成要用Invoke的写法,不是我想要的
18          await Task.Delay(10).ConfigureAwait(true);
19          progressBar1.Value = i;
20          
21      }
22  }

 2.使用Progress

 

 1         private async void button4_Click3(object sender, EventArgs e)
 2         {
 3             button4.Enabled = false;
 4             var progress = new Progress<double>(value=> progressBar1.Value = (int)value);
 5 
 6             await Dojob(progress);
 7             button4.Enabled = true;
 8          
 9         }
10 
11         private async Task Dojob3(IProgress<double> progress)
12         {
13             for (int i = 0; i <= 100; i++)
14             {
15                 //此处不将线程交给UI线程,仍然能实现更新UI
16                   await Task.Delay(10).ConfigureAwait(false);
17                   progress.Report(i);
18                 
19             }
20         }

3.自定义Myprocess

 1 using System.Numerics;
 2 
 3 class MyProgress<T> : Progress<T> where T : notnull
 4 {
 5     private readonly Action? _complete;
 6     private readonly T _maximum;
 7     private bool _isCompleted;
 8 
 9     public MyProgress(Action<T> handler, Action? complete, T maximum)
10     : base(handler)
11     {
12         _complete = complete;
13         _maximum = maximum;
14         ProgressChanged += CheckCompletion;
15 
16     }
17 
18     protected override void OnReport(T value)
19     {
20         if (_isCompleted) return;
21         base.OnReport(value);
22     }
23 
24 
25     private void CheckCompletion(object? sender, T e)
26     {
27         if (e.Equals(_maximum) && !_isCompleted)
28             _isCompleted = true;
29         _complete?.Invoke();
30     }
31 
32 }

调用:

 1   private async void button4_Click(object sender, EventArgs e)
 2   {
 3       button4.Enabled = false;
 4       var progress = new MyProgress<double>(value => progressBar1.Value = (int)value, () =>
 5       {
 6           button4.Enabled = true;
 7       },100);
 8       await Dojob(progress);
 9      
10 
11   }

 

posted @ 2024-12-09 22:51  小码哥-风云  阅读(3)  评论(0编辑  收藏  举报