生产消费者队列(TaskCompletionSource)的应用
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApplication6
{
public class PCQueue : IDisposable
{
class WorkItem
{
public readonly TaskCompletionSource<object> TaskSource;
public readonly Action Action;
public readonly CancellationToken? CancelToken; public WorkItem(
TaskCompletionSource<object> taskSource,
Action action,
CancellationToken? cancelToken)
{ TaskSource = taskSource;
Action = action;
CancelToken = cancelToken;
}
} BlockingCollection<WorkItem> _taskQ = new BlockingCollection<WorkItem>(); /// <summary>
/// 为每个消费者创建并启动单独的任务: 这里我启动了2个任务,用于打印easy和easy2这两个的顺序不一定
/// </summary>
/// <param name="workerCount"></param>
public PCQueue(int workerCount)
{
// 为每个消费者创建并启动单独的任务:
for (int i = ; i < workerCount; i++)
Task.Factory.StartNew(Consume);
} public void Dispose() { _taskQ.CompleteAdding(); } /// <summary>
/// 默认任务取消标识为null的任务进队方法
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public Task EnqueueTask(Action action)
{
return EnqueueTask(action, null);
}
/// <summary>
/// 任务进队方法含标识
/// </summary>
/// <param name="action"></param>
/// <param name="cancelToken"></param>
/// <returns></returns>
public Task EnqueueTask(Action action, CancellationToken? cancelToken)
{
var tcs = new TaskCompletionSource<object>();
_taskQ.Add(new WorkItem(tcs, action, cancelToken));
//通过TaskCompletionSource返回任务本身,可查看任务的响应信息如result,exception,status等等
return tcs.Task;
} void Consume()
{
foreach (WorkItem workItem in _taskQ.GetConsumingEnumerable())
if (workItem.CancelToken.HasValue &&
workItem.CancelToken.Value.IsCancellationRequested)
{
workItem.TaskSource.SetCanceled();
}
else
try
{
workItem.Action();
workItem.TaskSource.SetResult(); // 表示完成
}
catch (OperationCanceledException ex)
{
if (ex.CancellationToken == workItem.CancelToken)
workItem.TaskSource.SetCanceled();
else
workItem.TaskSource.SetException(ex);
}
catch (Exception ex)
{
workItem.TaskSource.SetException(ex);
}
}
}
class Program
{
static void Main(string[] args)
{
CancellationToken token1 = new CancellationToken(true);
//
var pcQ = new PCQueue();
Task task = pcQ.EnqueueTask(() => Console.WriteLine("Easy!"),token1);//输出easy的任务不会执行
task = pcQ.EnqueueTask(() => Console.WriteLine("Easy2!"));//会执行 // ...
Console.Read();
}
}
}
生产消费者队列(TaskCompletionSource)的应用的更多相关文章
- ZooKeeper实现生产-消费者队列
[欢迎关注公众号:程序猿讲故事 (codestory),及时接收最新文章] 生产-消费者队列,用于多节点的分布式数据结构,生产和消费数据.生产者创建一个数据对象,并放到队列中:消费者从队列中取出一个数 ...
- BlockingQueue 阻塞队列(生产/消费者队列)
1:BlockingQueue的继承关系 java.util.concurrent 包里的 BlockingQueue是一个接口, 继承Queue接口,Queue接口继承 Collection Blo ...
- Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型
Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: 每个对象都对应于一个可称为" 互斥锁&qu ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- RabbitMQ下的生产消费者模式与订阅发布模式
所谓模式,就是在某种场景下,一类问题及其解决方案的总结归纳.生产消费者模式与订阅发布模式是使用消息中间件时常用的两种模式,用于功能解耦和分布式系统间的消息通信,以下面两种场景为例: 数据接入 假设 ...
- Python——Queue模块以及生产消费者模型
1.了解Queue Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递 |queue.Qu ...
- Kafka下的生产消费者模式与订阅发布模式
原文:https://blog.csdn.net/zwgdft/article/details/54633105 在RabbitMQ下的生产消费者模式与订阅发布模式一文中,笔者以“数据接入”和“事 ...
- Linux——多线程下解决生产消费者模型
我们学习了操作系统,想必对生产消费者问题都不陌生.作为同步互斥问题的一个经典案例,生产消费者模型其实是解决实际问题的基础模型,解决很多的实际问题都会依赖于它.而此模型要解决最大的问题便是同步与互斥.而 ...
- 生产消费者模式与python+redis实例运用(中级篇)
上一篇文章介绍了生产消费者模式与python+redis实例运用(基础篇),但是依旧遗留了一个问题,就是如果消费者消费的速度跟不上生产者,依旧会浪费我们大量的时间去等待,这时候我们就可以考虑使用多进程 ...
随机推荐
- SQL Server2008 R2开启远程连接总结
============================== SQL Server2008 R2开启远程连接(最全总结) ============================== 安装过程:适用W ...
- python的继承顺序
python的继承顺序 python 创建类时分为新式类和旧式类 class A: # 经典类 def __init__(self): pass # 新类,可以在这里加 __metaclass__ = ...
- LG2831 愤怒的小鸟
题意 分析 看n的范围只有18,考虑状压dp. 用\(f(s)\)表示过集合s中的点所需最小的抛物线数量. 然后枚举点对算抛物线,判断其他点是否在抛物线上来转移. 细节 判断能否构成抛物线只需要判断斜 ...
- CH3301 同余方程
题意 3301 同余方程 0x30「数学知识」例题 描述 求关于 x的同余方程 ax ≡ 1(mod b) 的最小正整数解. 输入格式 输入只有一行,包含两个正整数a,b,用一个空格隔开. 输出格式 ...
- [CLPR] 用于加速训练神经网络的二阶方法
本文翻译自: http://www.codeproject.com/Articles/16650/Neural-Network-for-Recognition-of-Handwritten-Digi ...
- composer中文镜像
王赛先生维护的 phpcomposer 全局修改 composer config -g repo.packagist composer https://packagist.phpcomposer.co ...
- React性能优化 PureComponent
为什么使用? React15.3中新加了一个 PureComponent 类,顾名思义, pure 是纯的意思, PureComponent 也就是纯组件,取代其前身 PureRenderMixin ...
- Shell脚本的特性
bash shell特性 1.命令补全和文件路径补全, 如果写错无法补全 table 2.命令历史记忆功能history 3.别名功能alias.unalias 4.常用快捷键ctrl+u,k,a,e ...
- c# 类间关系
一.依赖关系 简单的理解,依赖就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的.临时性的.非常弱的,但是类B的变化会影响到类A.比如某人要过河,需要借用一条船,此时人与船之间的关 ...
- leetcode921
public class Solution { public int MinAddToMakeValid(string S) { Stack<char> ST = new Stack< ...