线程池-实现一个取消选项

代码Demo:

using System;
using System.Threading;

在Main方法下面加入以下代码片段:

static void AsyncOperation1(CancellationToken token)
{
Console.WriteLine("Starting the first task");
for (int i = 0; i < 5; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("The first task has been canceled.");
return;
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
Console.WriteLine("The first task has completed succesfully");
}
/// <summary>
///
/// </summary>
/// <param name="token"></param>
static void AsyncOperation2(CancellationToken token)
{
try
{
Console.WriteLine("Starting the second task");

for (int i = 0; i < 5; i++)
{
token.ThrowIfCancellationRequested();
Thread.Sleep(TimeSpan.FromSeconds(1));
}
Console.WriteLine("The second task has completed successfully");
}
catch (OperationCanceledException)//抛出OperationCanceledException异常
{
Console.WriteLine("The second task has been canceled.");
}
}
private static void AsyncOperation3(CancellationToken token)
{
bool cancellationFlag = false;
token.Register(() => cancellationFlag = true);//注册一个回调函数
Console.WriteLine("Starting the third task");
for (int i = 0; i < 5; i++)
{
if (cancellationFlag)
{
Console.WriteLine("The third task has been canceled.");
return;
}
Thread.Sleep(TimeSpan.FromSeconds(1));
}
Console.WriteLine("The third task has completed succesfully");
}

在Main方法中加入以下代码片段:

using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation1(token));
Thread.Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}

using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation2(token));
Thread.Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}

using (var cts = new CancellationTokenSource())
{
CancellationToken token = cts.Token;
ThreadPool.QueueUserWorkItem(_ => AsyncOperation3(token));
Thread.Sleep(TimeSpan.FromSeconds(2));
cts.Cancel();
}
Thread.Sleep(TimeSpan.FromSeconds(2));

工作原理:

本节中介绍了CancellationTokenSource和CancellationToken两个新类。他们在.NET4.0被引入,目前是实现异步操作的取消操作的事实标准。由于线程池已经存在了很长时间,并没有特殊的API来实现取消标记功能,但是仍然可以对线程池使用上述API。

在本程序中使用了三种方式来实现取消过程。第一个是轮询来检查CancellationToken.IsCancellationRequested属性。如果该属性为true,则说明操作需要被取消,我们必须放弃该操作。

第二种方式是跑出一个OperationCanceledException异常。这允许在操作之外控制取消过程,即需要取消操作时,通过操作之外的代码来处理。

最后一种方式是注册一个回调函数。当操作被取消时。,在线程池将调用该回调函数。这允许链式传递一个取消逻辑到另一个异步操作中。

原文地址:https://www.cnblogs.com/v-haoz/p/9272310.html

时间: 2024-08-05 14:03:36

线程池-实现一个取消选项的相关文章

转载:C++线程池的一个实现

原文转自:http://www.cnblogs.com/lidabo/p/3328646.html 略有修改 Cthread类参见:http://www.cnblogs.com/tangxin-blog/p/4835211.html CThreadPool.h 1 #ifndef __MY_THREAD_POOL_H_ 2 #define __MY_THREAD_POOL_H_ 3 4 #include "CThread.h" 5 #include <set> 6 #inc

spring 线程池 的一个坑。

问题简述: 配置的队列初始化的消费者线程占满了线程池.导致其他的再使用此线程池中线程不运行.不报错,不抛异常.线程的数量仅为为线程池的配置中的最小值. <task:executor pool-size="100-150" queue-capacity="250" > 同时schema描述中写道: The size of the executor's thread pool as either a single value or a range    (e

线程与线程池以及任务和协商式取消

一.线程 使用System.Threading命名空间下的Thread类即可创建专有线程 var t = new Thread(() => Console.WriteLine("new thread")); 构造函数有如下四个版本 Thread(ThreadStart start); public Thread(ThreadStart start, int maxStackSize); public Thread(ParameterizedThreadStart start);

Java线程池--ThreadPoolExecutor

一.线程池的处理流程 向线程池提交一个任务后,它的主要处理流程如下图所示: 一个线程从被提交(submit)到执行共经历以下流程: 线程池判断核心线程池里的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务.如果核心线程池里的线程都在执行任务,则进入下一个流程; 线程池判断工作队列是否已满.如果工作队列没有满,则将新提交的任务储存在这个工作队列里.如果工作队列满了,则进入下一个流程; 线程池判断其内部线程是否都处于工作状态.如果没有,则创建一个新的工作线程来执行任务.如果已满了,则

java自带线程池和队列详细讲解(转)

Java线程池使用说明 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的问题提供了非常大的帮助. 二:线程池 线程池的作用: 线程池作用就是限制系统中执行线程的数量.     根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪

自带线程池和队列详细讲解

Java线程池使用说明 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的问题提供了非常大的帮助. 二:线程池 线程池的作用: 线程池作用就是限制系统中执行线程的数量.      根 据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少

Java线程池使用说明

Java线程池使用说明 一 简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的问题提供了非常大的帮助. 二:线程池 线程池的作用: 线程池作用就是限制系统中执行线程的数量.     根 据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少

java并发之线程池Executor 核心源码解析

1.什么是线程池 定义:线程池是指管理一组同构工作线程的资源池 组成部分: 线程管理器(ThreadPool):用于创建并管理线程池.包括创建线程池,销毁线程池,添加新任务 工作线程(PoolWorker):线程池中的线程 任务接口(Task):每个任务必须实现的接口,一共工作线程调度任务的执行 任务队列:用于存放没有处理的任务,提供一种缓冲机制 2.为什么要使用线程池 通过重用现有的线程而不是创建新线程,从而减少了线程创建 和 销毁过程中的巨大开销 当请求到达时,工作线程已经存在,不用再等待线

深入浅出 Java Concurrency (29): 线程池 part 2 Executor 以及Executors[转]

Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 下面这张图完整描述了线程池的类体系结构. 首先Executor的execute方法只是执行一个Runnable的任务,当然了从某种角度上将最后的实现类也是在线程中启动此任务的.根据线程池的执行策略最后这个任务可能在新的线程中执行,或者线程池中的某个线程,甚至是调用者线程中执行(相当于直接运行Runnable的run方法).