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)的应用的更多相关文章

  1. ZooKeeper实现生产-消费者队列

    [欢迎关注公众号:程序猿讲故事 (codestory),及时接收最新文章] 生产-消费者队列,用于多节点的分布式数据结构,生产和消费数据.生产者创建一个数据对象,并放到队列中:消费者从队列中取出一个数 ...

  2. BlockingQueue 阻塞队列(生产/消费者队列)

    1:BlockingQueue的继承关系 java.util.concurrent 包里的 BlockingQueue是一个接口, 继承Queue接口,Queue接口继承 Collection Blo ...

  3. Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型

    Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: ​ ​ ​ 每个对象都对应于一个可称为" 互斥锁&qu ...

  4. Java多线程学习笔记--生产消费者模式

    实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...

  5. RabbitMQ下的生产消费者模式与订阅发布模式

    所谓模式,就是在某种场景下,一类问题及其解决方案的总结归纳.生产消费者模式与订阅发布模式是使用消息中间件时常用的两种模式,用于功能解耦和分布式系统间的消息通信,以下面两种场景为例: 数据接入   假设 ...

  6. Python——Queue模块以及生产消费者模型

    1.了解Queue Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递 |queue.Qu ...

  7. Kafka下的生产消费者模式与订阅发布模式

    原文:https://blog.csdn.net/zwgdft/article/details/54633105   在RabbitMQ下的生产消费者模式与订阅发布模式一文中,笔者以“数据接入”和“事 ...

  8. Linux——多线程下解决生产消费者模型

    我们学习了操作系统,想必对生产消费者问题都不陌生.作为同步互斥问题的一个经典案例,生产消费者模型其实是解决实际问题的基础模型,解决很多的实际问题都会依赖于它.而此模型要解决最大的问题便是同步与互斥.而 ...

  9. 生产消费者模式与python+redis实例运用(中级篇)

    上一篇文章介绍了生产消费者模式与python+redis实例运用(基础篇),但是依旧遗留了一个问题,就是如果消费者消费的速度跟不上生产者,依旧会浪费我们大量的时间去等待,这时候我们就可以考虑使用多进程 ...

随机推荐

  1. Windows10解决无法访问其他机器共享的问题

    你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访问.这些策略可帮助保护你的电脑免受网络上不安全设备或恶意设备的威胁. 管理员身份执行sc.exe config lanmanwork ...

  2. streamsets origin 说明

    origin 是streamsets pipeline的soure 入口,只能应用一个origin 在pipeline中, 对于运行在不同执行模式的pipeline 可以应用不同的origin 独立模 ...

  3. celery docker 基本使用

    项目参考官网资料,比较简单的add task 具体代码参考https://github.com/rongfengliang/celery-docker-demo 项目结构 ├── README.md ...

  4. linux svn soeasy

    http://blog.163.com/longsu2010@yeah/blog/static/173612348201202114212933/

  5. java.nio.charset.UnsupportedCharsetException: cp0

    使用jython调用python,提示console: Failed to install '': java.nio.charset.UnsupportedCharsetException: cp0. ...

  6. bzoj1811 mea

    Description 考虑一个非递减的整数序列 S1,....Sn+1(Si<=Si+1  1<=i<=n). 序列M1...Mn是定义在序列S的基础上,关系式为 Mi=( Si ...

  7. undefined和NAN的区别(转)

    Javascript 中 null.NaN和undefined的区别 1.类型分析: js中的数据类型有undefined,boolean,number,string,object等5种,前4种为原始 ...

  8. mysql安装过程及注意事项

    1.1. 下载: 我下载的是64位系统的zip包: 下载地址:https://dev.mysql.com/downloads/mysql/ 下载zip的包: 下载后解压:D:\软件安装包\mysql- ...

  9. 20165233 2017-2018-2 《Java程序设计》第七周学习总结

    20165233 2017-2018-2 <Java程序设计>第七周学习总结 教材学习内容总结 ch11 下载XAMPP 基本操作:连接数据库 基础:查询操作,更新.添加与删除操作 重点: ...

  10. Pthreads 环境配置,VisualStudio

    ▶ Visual Studio 下配置MPI环境 ● 下载 Pthreads(http://pthreads.org/),解压. ● 针对 x64 程序的配置 ■ 将 Pre-built.2\incl ...