使用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;
else
cts.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里面操作的是主线程里面的东西