三年前写过基于ConcurrentQueue的异步队列,今天在整理代码的时候发现当时另外一种实现方式-使用BlockingCollection实现,这种方式目前依然在实际项目中使用。关于BlockingCollection的基本使用请查阅MSDN源码实现

下面直接上代码:(代码已经放到了我的github上)

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using Danny.Infrastructure.Helper; namespace Danny.Infrastructure.Collections
{
/// <summary>
/// 一个基于BlockingCollection实现的多线程的处理队列
/// </summary>
public class ProcessQueue<T>
{
private BlockingCollection<T> _queue;
private CancellationTokenSource _cancellationTokenSource;
private CancellationToken _cancellToken;
//内部线程池
private List<Thread> _threadCollection; //队列是否正在处理数据
private int _isProcessing;
//有线程正在处理数据
private const int Processing = ;
//没有线程处理数据
private const int UnProcessing = ;
//队列是否可用
private volatile bool _enabled = true;
//内部处理线程数量
private int _internalThreadCount; public event Action<T> ProcessItemEvent;
//处理异常,需要三个参数,当前队列实例,异常,当时处理的数据
public event Action<dynamic,Exception,T> ProcessExceptionEvent; public ProcessQueue()
{
_queue=new BlockingCollection<T>();
_cancellationTokenSource = new CancellationTokenSource();
_internalThreadCount = ;
_cancellToken = _cancellationTokenSource.Token;
_threadCollection = new List<Thread>();
} public ProcessQueue(int internalThreadCount):this()
{
this._internalThreadCount = internalThreadCount;
} /// <summary>
/// 队列内部元素的数量
/// </summary>
public int GetInternalItemCount()
{
return _queue.Count;
} public void Enqueue(T items)
{
if (items == null)
{
throw new ArgumentException("items");
} _queue.Add(items);
DataAdded();
} public void Flush()
{
StopProcess(); while (_queue.Count != )
{
T item=default(T);
if (_queue.TryTake(out item))
{
try
{
ProcessItemEvent(item);
}
catch (Exception ex)
{
OnProcessException(ex,item);
}
}
}
} private void DataAdded()
{
if (_enabled)
{
if (!IsProcessingItem())
{
ProcessRangeItem();
StartProcess();
}
}
} //判断是否队列有线程正在处理
private bool IsProcessingItem()
{
return !(Interlocked.CompareExchange(ref _isProcessing, Processing, UnProcessing) == UnProcessing);
} private void ProcessRangeItem()
{
for (int i = ; i < this._internalThreadCount; i++)
{
ProcessItem();
}
} private void ProcessItem()
{
Thread currentThread = new Thread((state) =>
{
T item=default(T);
while (_enabled)
{
try
{
try
{
item = _queue.Take(_cancellToken);
ProcessItemEvent(item);
}
catch (OperationCanceledException ex)
{
DebugHelper.DebugView(ex.ToString());
} }
catch (Exception ex)
{
OnProcessException(ex,item);
}
} }); _threadCollection.Add(currentThread);
} private void StartProcess()
{
foreach (var thread in _threadCollection)
{
thread.Start();
}
} private void StopProcess()
{
this._enabled = false;
foreach (var thread in _threadCollection)
{
if (thread.IsAlive)
{
thread.Join();
}
}
_threadCollection.Clear();
} private void OnProcessException(Exception ex,T item)
{
var tempException = ProcessExceptionEvent;
Interlocked.CompareExchange(ref ProcessExceptionEvent, null, null); if (tempException != null)
{
ProcessExceptionEvent(this,ex,item);
}
} }
}

使用方法:

class Program
{
static void Main(string[] args)
{
ProcessQueue<int> processQueue = new ProcessQueue<int>();
processQueue.ProcessExceptionEvent += ProcessQueue_ProcessExceptionEvent;
processQueue.ProcessItemEvent += ProcessQueue_ProcessItemEvent; processQueue.Enqueue();
processQueue.Enqueue();
processQueue.Enqueue(); } /// <summary>
/// 该方法对入队的每个元素进行处理
/// </summary>
/// <param name="value"></param>
private static void ProcessQueue_ProcessItemEvent(int value)
{
Console.WriteLine(value);
} /// <summary>
/// 处理异常
/// </summary>
/// <param name="obj">队列实例</param>
/// <param name="ex">异常对象</param>
/// <param name="value">出错的数据</param>
private static void ProcessQueue_ProcessExceptionEvent(dynamic obj, Exception ex, int value)
{
Console.WriteLine(ex.ToString());
}
}

.Net中的并行编程-7.基于BlockingCollection实现高性能异步队列的更多相关文章

  1. .Net中的并行编程-1.路线图(转)

    大神,大神,膜拜膜拜,原文地址:http://www.cnblogs.com/zw369/p/3834559.html 目录 .Net中的并行编程-1.路线图 分析.Net里线程同步机制 .Net中的 ...

  2. .Net中的并行编程-4.实现高性能异步队列

    上文<.Net中的并行编程-3.ConcurrentQueue实现与分析>分析了ConcurrentQueue的实现,本章就基于ConcurrentQueue实现一个高性能的异步队列,该队 ...

  3. .Net中的并行编程-3.ConcurrentQueue实现与分析

    在上文<.Net中的并行编程-2.ConcurrentQueue的实现与分析> 中解释了无锁的相关概念,无独有偶BCL提供的ConcurrentQueue也是基于原子操作实现, 由于Con ...

  4. .Net中的并行编程-5.流水线模型实战

    自己在Excel整理了很多想写的话题,但苦于最近比较忙(其实这是借口).... 上篇文章<.Net中的并行编程-4.实现高性能异步队列>介绍了异步队列的实现,本篇文章介绍我实际工作者遇到了 ...

  5. .Net中的并行编程-2.ConcurrentStack的实现与分析

    在上篇文章<.net中的并行编程-1.基础知识>中列出了在.net进行多核或并行编程中需要的基础知识,今天就来分析在基础知识树中一个比较简单常用的并发数据结构--.net类库中无锁栈的实现 ...

  6. .Net中的并行编程-6.常用优化策略

                本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略.      一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...

  7. Python中的并行编程速度

    这里主要想记录下今天碰到的一个小知识点:Python中的并行编程速率如何? 我想把AutoTool做一个并行化改造,主要目的当然是想提高多任务的执行速度.第一反应就是想到用多线程执行不同模块任务,但是 ...

  8. .Net中的并行编程-1.路线图

    最近半年一直研究用.net进行并行程序的开发与设计,再研究的过程中颇有收获,所以画了一个图总结了一下并行编程的基础知识点,这些知识点是并行编程的基础,有助于我们编程高性能的程序,里面的某些结构实现机制 ...

  9. .NET Framework 4 中的并行编程9---线程安全集合类

    原文转载自:http://www.cnblogs.com/xray2005/archive/2011/10/11/2206745.html 在.Net 4中,新增System.Collections. ...

随机推荐

  1. 深入剖析Tomcat会话机制

    1缓存机制 Tomcat默认将Session保存到内存中.但同时,Tomcat也提供了PersistentManager配合不同的Store实现的方式,使Session可以被保存到不同地方(Datab ...

  2. Dynamics CRM 注册插件dll到GAC

    以server2012为例,搜索cmd,打开红框中的命令框,gacutil.exe -i "dll路径" 通过该命令把需要用到dll注册进gac(这里包括你的插件dll和你插件中引 ...

  3. J2EE进阶(十)SSH框架整合常见问题汇总(一)

    SSH框架整合常见问题汇总(一) 前言 以下所列问题具有针对性,但是遇到同类型问题时均可按照此思路进行解决. HTTP Status 404 - No result defined for actio ...

  4. 最简单的基于FFmpeg的封装格式处理:视音频复用器(muxer)

    ===================================================== 最简单的基于FFmpeg的封装格式处理系列文章列表: 最简单的基于FFmpeg的封装格式处理 ...

  5. 如何在Cocos2D游戏中实现A*寻路算法(五)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  6. [C++学习历程]Visual Studio 2010 中文旗舰版 安装

    作者: 苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/19765441 要开始学习C++了,先装个开发环境吧,没有选择最新的2 ...

  7. java设计模式---构建者模式

    创建者模式和工厂模式有点类似,不过关注点不同.工厂模式往往只关心你要的是什么,二不关心这个东西的具体细节是什么.而创建模式则关心的是这个东西的具体细节的创建.拿创建人物来说,我们关心的不仅是创建一个人 ...

  8. MySQL进阶(一)主外键讲解

    1.什么是外键: 作为外键的字段. REFERENCES:映射到主表的字段2. ON DELETE后面的四个参数:代表的是当删除主表的记录时,所做的约定. RESTRICT(限制):如果你想删除的那个 ...

  9. cocos2d-x初探

    今天把cocos2d-x下载下来装了准备试试. 就不用windows本了,主要想做iOS游戏,所以这里用mac. 先在http://cocos2d-x.org/download下载右边的cocos,然 ...

  10. [Android编程心得] Camera(OpenCV)自动对焦和触摸对焦的实现

    写在前面 最近在从零开始写一个移动端的AR系统,坑实在是太多了!!!整个项目使用了OpenCV第三方库,但对于摄像机来说,和原生Camera的方法基本相同. 实现 以OpenCV的JavaCamera ...