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)
        {
​
        }
    }
}
复制代码
相关推荐
hez20107 小时前
Runtime Async - 步入高性能异步时代
c#·.net·.net core·clr
mudtools20 小时前
.NET驾驭Word之力:玩转文本与格式
c#·.net
唐青枫1 天前
C#.NET 数据库开发提速秘籍:SqlSugar 实战详解
c#·.net
mudtools2 天前
.NET驾驭Word之力:理解Word对象模型核心 (Application, Document, Range)
c#·.net
大飞pkz2 天前
【设计模式】C#反射实现抽象工厂模式
设计模式·c#·抽象工厂模式·c#反射·c#反射实现抽象工厂模式
唐青枫2 天前
从入门到进阶:C#.NET Stopwatch 计时与性能测量全攻略
c#·.net
未来之窗软件服务2 天前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
1uther2 天前
Unity核心概念⑨:Screen
开发语言·游戏·unity·c#·游戏引擎
阿幸软件杂货间2 天前
Office转PDF转换器v1.0.py
开发语言·pdf·c#
sali-tec2 天前
C# 基于halcon的视觉工作流-章34-环状测量
开发语言·图像处理·算法·计算机视觉·c#