C#多线程之取消架构介绍

C#多线程之取消架构介绍攻略

什么是C#多线程取消架构

在C#中,我们可以使用多线程来进行异步编程,但是在实际场景中,有时候由于各种原因,我们需要中途取消一个正在运行的线程。而为了达到这个目的,C#中引入了取消架构(Cancellation Framework),通过这个机制,我们可以实现对多线程操作的取消。在该机制中,我们创建一个CancellationTokenSource的实例,然后将它的Token对象传递给所有的任务,并在需要取消这些任务时,调用该Token对象的Cancel方法即可。

如何使用C#多线程取消架构

创建CancellationTokenSource实例

我们先创建一个CancellationTokenSource实例:

CancellationTokenSource cts = new CancellationTokenSource();

异步执行需要取消的任务

我们有一个需要被取消的异步任务,这个任务可能需要运行几秒钟或几分钟,我们可以使用Task.Run方法来启动这个任务,并将CancellationTokenSource的Token对象作为参数传入:

var task = Task.Run(() => {
    // 执行需要被取消的任务
    // 可以使用while循环来模拟一个长时间任务,这里使用Thread.Sleep来模拟
    int i = 0;
    while (true) {
        if (cts.Token.IsCancellationRequested) {
            break;
        }
        Console.WriteLine("Task is running: {0}", ++i);
        Thread.Sleep(1000);
    }
    Console.WriteLine("Task is finished.");
}, cts.Token);

在该任务中,我们使用了while循环,并且在每次循环中都检测CancellationTokenSource的Token对象是否被取消,如果是,则跳出循环,结束任务。这里我们使用Thread.Sleep方法来模拟一个长时间运行的任务。

取消任务

当我们需要取消该异步任务时,可以直接调用CancellationTokenSource的Cancel方法即可:

cts.Cancel();

Cancel方法将会通知所有使用该Token对象的任务,并使这些任务停止运行。

检查任务是否被取消

我们也可以在任务中检查Token是否被取消,如果是,则立即停止任务:

for (int i = 0; i < 10; i++) {
    if (cts.Token.IsCancellationRequested) {
        Console.WriteLine("Task is cancelled.");
        return;
    }
    Console.WriteLine("Task is running: {0}", i);
    Thread.Sleep(1000);
}
Console.WriteLine("Task is finished.");

示例一:向多个URL异步请求数据

下面我们来看一个使用C#多线程取消架构的例子,假设我们需要从多个URL异步请求数据,并将它们合并到一个结果中:

async Task<string> GetDataAsync(string url, CancellationToken ct) {
    using (HttpClient client = new HttpClient()) {
        using (HttpResponseMessage response = await client.GetAsync(url, ct)) {
            var data = await response.Content.ReadAsStringAsync();
            return data;
        }
    }
}

async Task<string> GetDataFromUrlsAsync(string[] urls, CancellationToken ct) {
    List<Task<string>> tasks = new List<Task<string>>();
    foreach (string url in urls) {
        tasks.Add(GetDataAsync(url, ct));
    }

    string[] result = await Task.WhenAll(tasks.ToArray());
    return string.Join(",", result);
}

在该例子中,我们首先定义了一个GetDataAsync方法来异步获取指定URL的数据,该方法使用HttpClient来发起网络请求,并将获取到的数据返回。

然后我们定义了一个GetDataFromUrlsAsync方法来同时从多个URL请求数据,并将它们合并到一个结果中。在该方法中,我们使用List>来保存从每个URL请求数据的任务,然后使用Task.WhenAll方法等待所有任务完成,并将它们返回的数据合并到结果中。

最后我们调用该方法,并在需要取消请求时,调用CancellationTokenSource的Cancel方法:

CancellationTokenSource cts = new CancellationTokenSource();
string[] urls = new string[] { "http://url1.com", "http://url2.com", "http://url3.com" };
Task<string> task = GetDataFromUrlsAsync(urls, cts.Token);
cts.CancelAfter(TimeSpan.FromSeconds(5));
try {
    string result = await task;
    Console.WriteLine(result);
} catch (TaskCanceledException) {
    Console.WriteLine("Task is cancelled.");
}

在该代码中,我们首先创建一个CancellationTokenSource实例,并将它的Token对象传递给GetDataFromUrlsAsync方法。然后我们调用该方法,使用string[]数组来保存需要请求的URL。

在调用方法后,我们使用cts.CancelAfter方法来5秒钟后自动取消请求,在等待方法返回的过程中,如果任务被取消,则会抛出TaskCanceledException异常,我们可以在catch块中处理这个异常。

示例二:使用Parallel.ForEach执行任务

在下面这个例子里,我们使用Parallel.ForEach方法来执行多个任务,而使用CancellationTokenSource来取消所有任务:

var cts = new CancellationTokenSource();
string[] urls = new string[] { "http://url1.com", "http://url2.com", "http://url3.com" };
try {
    Parallel.ForEach(urls, new ParallelOptions { CancellationToken = cts.Token }, url => {
        // 执行任务,这里使用HttpClient来请求数据
        using (var client = new HttpClient()) {
            var response = client.GetAsync(url, cts.Token).Result;
            Console.WriteLine(response.Content.ReadAsStringAsync().Result);
        }
    });
} catch (OperationCanceledException) {
    Console.WriteLine("Tasks are cancelled.");
}

在该例子中,我们使用Parallel.ForEach方法来并行执行多个任务,使用CancellationTokenSource的Token对象来取消所有任务。我们使用using语句来管理HttpClient的生命周期,并在任务中使用HttpClient来请求网络数据。

最后我们使用try-catch块来捕获OperationCanceledException异常,该异常会在任务被取消时抛出。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#多线程之取消架构介绍 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • C#在Unity游戏开发中进行多线程编程的方法

    C#在Unity游戏开发中进行多线程编程的方法 在Unity游戏开发中,多线程编程可以提高游戏性能和可玩性,让游戏更加流畅。而在C#中,我们可以使用Thread类来进行多线程编程。 使用Thread类进行多线程编程 Thread类是.NET中用于创建和管理线程的类。在Unity游戏开发中,我们可以使用它来创建和管理多线程。 创建线程 创建线程有两种方式,一种…

    C# 2023年5月15日
    00
  • python将图片文件转换成base64编码的方法

    将图片文件转换成base64编码是一种常见的操作,可以将图片文件转换成字符串形式,方便在网络传输中使用。在Python中,我们可以使用base64模块来实现将图片文件转换成base64编码的操作。以下是详细的攻略,包括两个示例。 使用base64模块将图片文件转换成base64编码 要将图片文件转换成base64编码,我们需要使用Python的base64模…

    C# 2023年5月15日
    00
  • C#实现文字视频生成器的示例代码

    让我为您详细讲解一下“C#实现文字视频生成器的示例代码”的完整攻略。 简介 文字视频生成器是一种将文本内容转换为视频的工具,通常用来制作广告、宣传视频等。本攻略将介绍如何使用C#实现一个简单的文字视频生成器。 准备工作 要实现文字视频生成器,我们需要使用到以下工具和库: C#编程语言 FFmpeg:一个跨平台的视频处理工具,可以通过命令行方式调用 Emgu.…

    C# 2023年6月6日
    00
  • .NET中保证线程安全的高级方法Interlocked类使用介绍

    Interlocked类是.NET Framework中保证线程安全的高级方法之一,其主要提供了一系列原子操作,用于保护资源的访问并防止数据竞争。下面将对Interlocked类进行介绍。 一、Interlocked类概述 Interlocked类是System.Threading命名空间中的一个类,包含了一组原子操作方法,该方法能够保证一个指定地址上的操作…

    C# 2023年6月7日
    00
  • C#实现数字华容道游戏

    C#实现数字华容道游戏攻略 数字华容道是一种写有数字的拼图游戏,其目标是将拼图换成数字顺序正确的拼图。本文将详细讲解如何使用C#实现数字华容道游戏。 步骤1:设计游戏界面 数字华容道游戏需要一个图形界面来展示拼图。这个界面需要具备以下特点: 一个接受用户输入的拼图区域 拥有重新开始游戏和退出游戏的按钮 展示游戏进度的进度条或得分界面 步骤2:生成数字华容道 …

    C# 2023年6月6日
    00
  • ASP.net(c#)生成条形码 code39条码生成方法

    下面是“ASP.net(c#)生成条形码 code39条码生成方法”的完整攻略。 什么是Code39条形码 Code39是一种常用的线性条形码,由数字、字母、还有一些特殊字符组成。Code39条形码可以表示0到9的数字、26个大写字母、7个特殊字符和一个空格符号。 生成Code39条形码的步骤 ASP.NET生成Code39条形码的步骤大致如下: 安装Cod…

    C# 2023年5月31日
    00
  • C# Console.WriteLine()方法: 将指定字符串和行结束符写入标准输出流

    作用: Console.WriteLine()是C#中标准输出的方法,用于将指定的数据写入控制台。它可以输出各种类型的值,如字符串、数字、布尔值以及其他对象等等。 使用方法: 方法语法如下: Console.WriteLine(); Console.WriteLine(string value); Console.WriteLine(string forma…

    C# 2023年4月19日
    00
  • C#编程实现Excel文档中搜索文本内容的方法及思路

    C#编程实现Excel文档中搜索文本内容的方法及思路 在 C# 编程中,实现搜索 Excel 文档中的文本内容是一个常见的需求。本文将介绍如何使用 C# 进行 Excel 文档的搜索文本内容,并附带两个示例说明。 思路 实现搜索 Excel 文档中的文本内容,可以采用以下步骤: 打开需要搜索的 Excel 文档。 遍历 Excel 文档中的所有单元格,查找包…

    C# 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部