使用Task写一个进度条
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _5.任务
{public partial class Form1 : Form{Task task = null;// 取消的标识符,专门用来管理Task。CancellationTokenSource对象可以生成CancellationToken// CancellationTokenSource对象还可以取消任务CancellationTokenSource cts;bool isPause = false; // 是否暂停public Form1(){InitializeComponent();// 实例化取消任务的标识cts = new CancellationTokenSource();// 实例化任务(创建一个分线程)task = new Task(new Action<object>(UpdateProgressBar), 0, cts.Token);}
private void UpdateProgressBar(object state){while (!cts.IsCancellationRequested && !isPause){task.Wait(100);Invoke(new Action(() =>{state = (int)state + 1;if ((int)state <= 100)progressBar1.Value = (int)state;elsects.Cancel(); // 取消任务后,会影响IsCancellationRequested属性}));}}private void button1_Click(object sender, EventArgs e){task.Start();}
private void button2_Click(object sender, EventArgs e){isPause = true;}
private void button3_Click(object sender, EventArgs e){isPause = false;cts = new CancellationTokenSource();task = new Task(new Action<object>(UpdateProgressBar), this.progressBar1.Value, cts.Token);task.Start();}
private void button4_Click(object sender, EventArgs e){isPause = true;cts.Cancel();}}
}
CancellationTokenSource怎么使用
CancellationTokenSource
是.NET中用于异步编程的一个类,它允许你创建一个 CancellationToken
,这个令牌可以被传递给异步操作,以便在需要时请求取消操作。以下是 CancellationTokenSource
的基本用法:
创建 CancellationTokenSource
CancellationTokenSource cts = new CancellationTokenSource();
获取 CancellationToken
从 CancellationTokenSource
实例中获取 CancellationToken
,然后将它传递给需要支持取消的异步操作。
CancellationToken token = cts.Token;
传递给异步操作
将 CancellationToken
作为参数传递给支持取消的异步方法。
await SomeAsyncOperationAsync(token);
请求取消
当你需要取消操作时,调用 CancellationTokenSource
的 Cancel
方法。
cts.Cancel();
处理取消
在异步方法中,检查 CancellationToken
是否被触发,并在需要时处理取消逻辑。
public async Task SomeAsyncOperationAsync(CancellationToken cancellationToken)
{try{while (!cancellationToken.IsCancellationRequested){// 执行一些工作
// 定期检查取消请求cancellationToken.ThrowIfCancellationRequested();
// 模拟工作延迟await Task.Delay(1000);}}catch (OperationCanceledException){// 处理取消操作Console.WriteLine("Operation was canceled.");}
}
完整示例
class Program
{static async Task Main(string[] args){CancellationTokenSource cts = new CancellationTokenSource();CancellationToken token = cts.Token;
// 启动异步操作Task asyncOperation = SomeAsyncOperationAsync(token);
// 假设5秒后用户请求取消await Task.Delay(5000);cts.Cancel();
try{// 等待异步操作完成或抛出异常await asyncOperation;}catch (OperationCanceledException){Console.WriteLine("The operation was canceled.");}}
static async Task SomeAsyncOperationAsync(CancellationToken cancellationToken){for (int i = 0; i < 10; i++){Console.WriteLine($"Working... {i}");await Task.Delay(1000, cancellationToken);
if (cancellationToken.IsCancellationRequested){Console.WriteLine("Cancellation was requested.");throw new OperationCanceledException(cancellationToken);}}}
}
SomeAsyncOperationAsync
方法执行一些工作,并定期检查是否收到了取消请求。如果在5秒后调用了 cts.Cancel()
,那么 CancellationTokenSource
会发出取消请求,并且异步操作将捕获 OperationCanceledException
异常来处理取消。
使用 CancellationTokenSource
和 CancellationToken
提供了一种优雅的方式来请求和响应取消操作,使异步编程更加灵活和健壮。
使用Task写一个进度条
using System;
using System.Threading;
using System.Windows.Forms;
namespace _2.Thread课堂练习
{public partial class Form1 : Form{Thread t = null; // 线程实例bool isCancel = false; // 取消标识public Form1(){InitializeComponent();
t = new Thread(UpdateProgressBar);this.button2.Enabled = false;this.button3.Enabled = false;this.button4.Enabled = false;}
private void UpdateProgressBar(object step){while (!isCancel && t != null && Convert.ToInt32(step) < 100){Thread.Sleep(100);step = Convert.ToInt32(step) + 1;
if (Convert.ToInt32(step) <= 100){Invoke(new Action(() =>{progressBar1.Value = Convert.ToInt32(step);}));}else{isCancel = true;}}}
private void button1_Click(object sender, EventArgs e){t?.Start(0);this.button1.Enabled = false;this.button2.Enabled = true;this.button4.Enabled = true;}
private void button2_Click(object sender, EventArgs e){t?.Suspend();this.button2.Enabled = false;this.button3.Enabled = true;}
private void button3_Click(object sender, EventArgs e){t?.Resume();this.button2.Enabled = true;this.button3.Enabled = false;this.button4.Enabled = true;}
private void button4_Click(object sender, EventArgs e){isCancel = true;t?.Abort();this.button1.Enabled = true;this.button2.Enabled = false;this.button3.Enabled = false;this.button4.Enabled = false;t = new Thread(UpdateProgressBar);progressBar1.Value = 0;isCancel = false;}
private void Form1_FormClosing(object sender, FormClosingEventArgs e){isCancel = true;t?.Abort();}
private void Form1_Load(object sender, EventArgs e){
}}
}
注意:Invoke里面不能写卡线程的东西,Invoke里面操作的是主线程里面的东西