C#中的多线程案例

使用Task写一个进度条

cs 复制代码
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

cs 复制代码
CancellationTokenSource cts = new CancellationTokenSource();

获取 CancellationToken

CancellationTokenSource 实例中获取 CancellationToken,然后将它传递给需要支持取消的异步操作。

cs 复制代码
CancellationToken token = cts.Token;

传递给异步操作

CancellationToken 作为参数传递给支持取消的异步方法。

cs 复制代码
await SomeAsyncOperationAsync(token);

请求取消

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

cs 复制代码
cts.Cancel();

处理取消

在异步方法中,检查 CancellationToken 是否被触发,并在需要时处理取消逻辑。

cs 复制代码
public async Task SomeAsyncOperationAsync(CancellationToken cancellationToken)
{
    try
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            // 执行一些工作
​
            // 定期检查取消请求
            cancellationToken.ThrowIfCancellationRequested();
​
            // 模拟工作延迟
            await Task.Delay(1000);
        }
    }
    catch (OperationCanceledException)
    {
        // 处理取消操作
        Console.WriteLine("Operation was canceled.");
    }
}

完整示例

cs 复制代码
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写一个进度条

cs 复制代码
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)
        {
​
        }
    }
}
复制代码
相关推荐
格林威1 小时前
Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型和EasyOCR实现汽车牌照动态检测和识别(C#代码,UI界面版)
人工智能·深度学习·数码相机·yolo·c#·汽车·视觉检测
Aczone281 小时前
Linux 软件编程(九)网络编程:IP、端口与 UDP 套接字
linux·网络·网络协议·tcp/ip·http·c#
chenglin0163 小时前
C#_接口设计:角色与契约的分离
java·前端·c#
谷宇.16 小时前
【Unity3D实例-功能-拔枪】角色拔枪(三)IK的使用-紧握武器
游戏·unity·c#·unity3d·游戏开发·游戏编程·steam
用户83562907805117 小时前
C# 从 PDF 提取图片教程
后端·c#
格林威19 小时前
Baumer高防护相机如何通过YoloV8深度学习模型实现网球运动员和网球速度的检测分析(C#代码UI界面版)
人工智能·深度学习·数码相机·yolo·ui·c#·视觉检测
hixiong12320 小时前
用OpencvSharp编写视频录制工具
opencv·c#·音视频
张飞洪21 小时前
C# 13 与 .NET 9 跨平台开发实战:基于.NET 9 与 EF Core 9 的现代网站与服务开发
开发语言·c#·.net
hixiong1231 天前
C# OpencvSharp获取Astra Pro奥比中光深度相机深度图
数码相机·opencv·计算机视觉·c#