C#中的多线程案例

使用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);

请求取消

当你需要取消操作时,调用 CancellationTokenSourceCancel 方法。

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 异常来处理取消。

使用 CancellationTokenSourceCancellationToken 提供了一种优雅的方式来请求和响应取消操作,使异步编程更加灵活和健壮。

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值