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. AlertDialog中使用ListView绑定数据

    在实际工作过程中,单单使用AlertDialog的单选功能不一定能满足我们的需求,需要绑定数据到 listview 1. 自定义Layout LayoutInflater factory = Layo ...

  2. Oracle序列和伪表

    创建序列 create sequence sq_teacher_tnostart with 10 从哪一个数字开始increment by 1 每次增长的数字maxvalue 999999999999 ...

  3. LoadRunner安装+破解+汉化

    安装 一.需要准备的东东: 1.电脑的操作系统:Win7旗舰版(不解释,这个版本安装问题最少了) 2.LoadRunner11+破解文件+汉化文件+删除注册表工具 3.强大的搜索引擎 二.安装过程 用 ...

  4. Spring Could与Dubbo、Docker、K8S

    如果你是在一个中小型项目中应用Spring Cloud,那么你不需要太多的改造和适配,就可以实现微服务的基本功能.但是如果是在大型项目中实践微服务,可能会发现需要处理的问题还是比较多,尤其是项目中老代 ...

  5. CentOS 7安装TigerVNC Server

    http://blog.csdn.net/wamath/article/details/76003128 1. CentOS 7安装TigerVNC Server 本文介绍如何在CentOS 7上安装 ...

  6. Sql Server中执行计划的缓存机制

    Sql查询过程 当执行一个Sql语句或者存储过程时, Sql Server的大致过程是 1. 对查询语句进行分析,将其生成逻辑单元,并进行基本的语法检查 2. 生成查询树(会将查询语句中所有操作转换为 ...

  7. 【monkeyrunner】monkeyrunner 的主要API和实例

    MonkeyRunner简介 monkeyrunner工具提供了编写控制Android设备或仿真器从Android的代码之外程序的API.随着monkeyrunner,您可以编写安装一个Android ...

  8. bzoj4558: [JLoi2016]方

    Description 上帝说,不要圆,要方,于是便有了这道题.由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形 上帝把我们派到了一个有N行M列的方格图上,图上一共有(N+1)×(M+1) ...

  9. Office 2016激活教程(附KMS激活软件)

    首先下载office 2016办公软件文件名:cn_office_professional_plus_2016_x86_x64_dvd_6969182.isoSHA1:277926A41B472EE3 ...

  10. Java之MD5加密

    一.Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321(R.Riv ...