C# 使用CancellationTokenSource取消多线程

下面我将详细讲解“C#使用CancellationTokenSource取消多线程”的完整攻略。

什么是 CancellationTokenSource

CancellationTokenSource是用来控制CancellationToken的一个类型,CancellationToken是一种用于取消例如Task、ThreadPoolWaitHandle和PLINQ等等API的执行的机制。 CancellationTokenSource的主要作用是创建用于请求取消操作的 CancellationToken。

CancellationTokenSource的使用方法

创建 CancellationTokenSource

首先我们需要创建一个CancellationTokenSource才能开始操作。可以使用无参数构造函数创建默认情况下不存在任何请求取消操作的 CancellationTokenSource,也可以使用一个int类型的参数构造函数创建可以在指定的毫秒数内自动取消的 CancellationTokenSource。

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

发出取消请求

我们可以使用CancellationTokenSource对象的Cancel方法取消与之关联的所有 CancellationToken。 当取消请求发出后,与 CancellationToken 关联的任务应该立即停止执行,这样可以快速地屏蔽后续进一步的资源密集型操作。我们可以在需要的地方直接调用Cancel方法来发起取消请求。

cancellationTokenSource.Cancel();

是否收到取消请求

通过CancellationToken.IsCancellationRequested属性可以检测与 CancellationToken 关联的请求是否收到取消请求。 以下代码演示了如何执行具有取消选项的异步操作:

public async Task DoAsyncWork(CancellationToken token)
{
    while (!token.IsCancellationRequested)
    {
        // TODO: 执行异步操作
    }

    // 如果收到取消请求,立即抛出OperationCanceledException。
    token.ThrowIfCancellationRequested();
}

与Task关联

现在我们需要让某个Task与CancellationToken关联,以便在取消请求发出后能够响应它们。可以使用Task的Cancellation属性来指定CancellationToken。

Task.Run(() =>
{
    // TODO: 执行需要取消请求的任务
}, cancellationTokenSource.Token);

取消等待的操作

ThreadPool.WaitHandle 也支持 CancellationToken。 取消等待的操作可以通过静态WaitHandle.WaitAny(WaitHandle[], CancellationToken) 或 ThreadPool.RegisterWaitForSingleObject(WaitHandle, delegate, object, int, bool)进行。

示例1

下面是一个简单的示例。程序首先创建了一个CancellationTokenSource,然后启动一个任务,该任务将在指定的时间内循环运行,同时检查CancellationToken,在任务运行的过程中如果取消请求收到则退出循环。

static async Task CancellationTokenExample1(CancellationTokenSource cancellationTokenSource)
{
    Console.WriteLine("开始任务");
    try
    {
        // 执行异步操作,如果在指定时间内完成,就等待响应
        await Task.Delay(3000, cancellationTokenSource.Token);
        Console.WriteLine("任务15秒之后完成了!");
    }
    catch (TaskCanceledException)
    {
        Console.WriteLine("任务收到取消请求!");
    }

    Console.WriteLine("任务结束!");
}

示例2

下面是另一个更复杂的示例,演示如何使用CancellationTokenSource来取消线程池中的操作。

首先定义了一个StartTime,然后在循环中定义了每个线程池中处理的任务,并在执行任务时检查CancellationToken是否已经收到取消请求。

static void CancellationTokenExample2(CancellationTokenSource cancellationTokenSource)
{
    var startTime = DateTime.UtcNow;
    var handles = new[] { new AutoResetEvent(false) };

    Console.WriteLine($"开始任务 {startTime:O}");

    var token = cancellationTokenSource.Token;

    ThreadPool.QueueUserWorkItem(_ => {
        try
        {
            var waitTime = 1000;
            Console.WriteLine($"开启线程1,等待{waitTime}秒");

            while (!token.IsCancellationRequested)
            {
                if (DateTime.UtcNow.Subtract(startTime).Seconds > 15)
                {
                    cancellationTokenSource.Cancel();
                }

                Task.Delay(waitTime, token).Wait(token); // 等待操作
                Console.WriteLine($"线程1等待了{waitTime}秒后完成了它的工作。");
                handles[0].Set();
            }

            Console.WriteLine("取消操作完成。");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("线程1收到取消请求。");
        }
    }, null);

    ThreadPool.RegisterWaitForSingleObject(handles[0], _ => {
        try
        {
            var waitTime = 500;
            Console.WriteLine("开启线程2,等待500毫秒");
            Task.Delay(waitTime).Wait(token);
            Console.WriteLine("线程2等待500毫秒后完成了它的工作。");
            handles[0].Set();
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("线程2收到取消请求。");
        }
    }, null, TimeSpan.FromSeconds(1), false);

    WaitHandle.WaitAll(handles);
    Console.WriteLine("任务结束!");
}

这样就完成了使用CancellationTokenSource来取消多线程的攻略了,希望本文能够帮助到你。

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

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

相关文章

  • C#中日期时间的简单操作

    C#中日期时间的简单操作 在C#中,日期时间类型是一种非常常见的数据类型。C#提供了许多方法和属性来操作和处理日期时间,使得处理日期时间变得十分方便。接下来将介绍C#中日期时间的简单操作攻略。 获取当前时间 可以使用DateTime.Now属性来获取当前的日期时间。例如: DateTime now = DateTime.Now; 获取当前时间的各个部分 可以…

    C# 2023年5月15日
    00
  • 分享两种实现Winform程序的多语言支持的多种解决方案

    接下来我将详细讲解Winform程序实现多语言支持的多种解决方案。 1. 利用Resx文件实现多语言支持 Resx文件是.NET中专门用于多语言支持的文件格式,可以用来存储不同语言的文本信息,在程序中通过读取Resx文件来实现不同语言的界面显示。 1.1 创建Resx文件 创建Resx文件有多种方式,这里以Visual Studio为例。 在Visual S…

    C# 2023年6月7日
    00
  • C#实现JSON字符串序列化与反序列化的方法

    下面是详细的C#实现JSON字符串序列化与反序列化的方法攻略: 一、什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript语言的一个子集,但是采用了类似于C语言家族的语法。JSON的格式比较简单明了且轻便,能够更好地支持Web端的数据交互,因此被广泛应用。 二、JSON序列化与反…

    C# 2023年5月31日
    00
  • C# Xamarin利用ZXing.Net.Mobile进行扫码的方法

    以下是C# Xamarin利用ZXing.Net.Mobile进行扫码的方法的完整攻略: 1. ZXing.Net.Mobile的介绍 1.1 什么是ZXing.Net.Mobile ZXing.Net.Mobile是一款基于ZXing的二维码扫描框架,支持多种平台,包括Xamarin.Android、Xamarin.iOS、Windows Phone、Wi…

    C# 2023年6月3日
    00
  • asp.net webservice返回json的方法

    当我们使用ASP.NET Web Service时,返回JSON格式数据是常见的需求。下面是ASP.NET Web Service返回JSON格式数据的完整攻略: 步骤1:创建Web服务 首先,需要在ASP.NET项目中创建Web服务。可以在Visual Studio中选择“新建项目”->“ASP.NET Web应用程序”,然后选择“Web服务”模板进…

    C# 2023年5月31日
    00
  • 浅谈ASP.NET Core中间件实现分布式 Session

    浅谈ASP.NET Core中间件实现分布式 Session攻略 在ASP.NET Core中,Session是一种用于存储用户数据的机制。在本攻略中,我们将讨论如何使用ASP.NET Core中间件Middleware实现分布式Session,并提供两个示例说明。 分布式Session的工作原理 在ASP.NET Core中,Session是一种用于存储用…

    C# 2023年5月17日
    00
  • WPF实现钟表效果

    下面我会为你详细讲解“WPF实现钟表效果”的完整攻略。 一、准备工作 1. 新建WPF应用程序 首先,我们需要新建一个WPF应用程序。 2. 引用PresentationCore、PresentationFramework、WindowsBase三个文件 在新建的WPF应用程序中,我们需要添加 PresentationCore、PresentationFra…

    C# 2023年6月1日
    00
  • C# WinForm国际化实现的简单方法

    那么下面我来详细讲解一下“C# WinForm国际化实现的简单方法”。 什么是国际化 国际化(Internationalization),简称I18N,指将软件(尤其是在开发过程中)设计成可同时支持多种语言和字符集的技术。通俗点说,国际化就是将我们的程序在不同地区、不同语言下也能够顺利运行,显示相应的语言文本和界面信息。 WinForm国际化实现的简单方法 …

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