c# 安全队列
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AA
{
public class AsynQueue<T>
{
//队列是否正在处理数据
private int isProcessing;
//有线程正在处理数据
private const int Processing = 1;
//没有线程处理数据
private const int UnProcessing = 0;
//队列是否可用
private volatile bool enabled = true;
private Task currentTask;
public event Action<T> ProcessItemFunction;
public event EventHandler<EventArgs<Exception>> ProcessException;
private ConcurrentQueue<T> queue;
public AsynQueue()
{
queue = new ConcurrentQueue<T>();
Start();
}
public int Count
{
get
{
return queue.Count;
}
}
private void Start()
{
Thread process_Thread = new Thread(PorcessItem);
process_Thread.IsBackground = true;
process_Thread.Start();
}
public void Enqueue(T items)
{
if (items == null)
{
throw new ArgumentException("items");
}
queue.Enqueue(items);
DataAdded();
}
//数据添加完成后通知消费者线程处理
private void DataAdded()
{
if (enabled)
{
if (!IsProcessingItem())
{
currentTask = Task.Factory.StartNew(ProcessItemLoop);
}
}
}
//判断是否队列有线程正在处理
private bool IsProcessingItem()
{
return !(Interlocked.CompareExchange(ref isProcessing, Processing, UnProcessing) == 0);
}
private void ProcessItemLoop()
{
if (!enabled && queue.IsEmpty)
{
Interlocked.Exchange(ref isProcessing, 0);
return;
}
T publishFrame;
if (queue.TryDequeue(out publishFrame))
{
try
{
ProcessItemFunction(publishFrame);
}
catch (Exception ex)
{
OnProcessException(ex);
}
}
if (enabled && !queue.IsEmpty)
{
currentTask = Task.Factory.StartNew(ProcessItemLoop);
}
else
{
Interlocked.Exchange(ref isProcessing, UnProcessing);
}
}
/// <summary>
///定时处理线程调用函数
///主要是监视入队的时候线程 没有来的及处理的情况
/// </summary>
private void PorcessItem(object state)
{
int sleepCount = 0;
int sleepTime = 1000;
while (enabled)
{
//如果队列为空则根据循环的次数确定睡眠的时间
if (queue.IsEmpty)
{
if (sleepCount == 0)
{
sleepTime = 1000;
}
else if (sleepCount <= 3)
{
sleepTime = 1000 * 3;
}
else
{
sleepTime = 1000 * 50;
}
sleepCount++;
Thread.Sleep(sleepTime);
}
else
{
//判断是否队列有线程正在处理
if (enabled && Interlocked.CompareExchange(ref isProcessing, Processing, UnProcessing) == 0)
{
if (!queue.IsEmpty)
{
currentTask = Task.Factory.StartNew(ProcessItemLoop);
}
else
{
Interlocked.Exchange(ref isProcessing, 0);
}
sleepCount = 0;
sleepTime = 1000;
}
}
}
}
public void Flsuh()
{
Stop();
if (currentTask != null)
{
currentTask.Wait();
}
while (!queue.IsEmpty)
{
try
{
T publishFrame;
if (queue.TryDequeue(out publishFrame))
{
ProcessItemFunction(publishFrame);
}
}
catch (Exception ex)
{
OnProcessException(ex);
}
}
currentTask = null;
}
public void Stop()
{
this.enabled = false;
}
private void OnProcessException(System.Exception ex)
{
var tempException = ProcessException;
Interlocked.CompareExchange(ref ProcessException, null, null);
if (tempException != null)
{
ProcessException(ex, new EventArgs<Exception>(ex));
}
}
[Serializable]
public class EventArgs<T> : System.EventArgs
{
public T Argument;
public EventArgs() : this(default(T))
{
}
public EventArgs(T argument)
{
Argument = argument;
}
}
}
}
c# 安全队列的更多相关文章
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- 消息队列 Kafka 的基本知识及 .NET Core 客户端
前言 最新项目中要用到消息队列来做消息的传输,之所以选着 Kafka 是因为要配合其他 java 项目中,所以就对 Kafka 了解了一下,也算是做个笔记吧. 本篇不谈论 Kafka 和其他的一些消息 ...
- Beanstalkd一个高性能分布式内存队列系统
高性能离不开异步,异步离不开队列,内部是Producer-Consumer模型的原理. 设计中的核心概念: job:一个需要异步处理的任务,是beanstalkd中得基本单元,需要放在一个tube中: ...
- .net 分布式架构之业务消息队列
开源QQ群: .net 开源基础服务 238543768 开源地址: http://git.oschina.net/chejiangyi/Dyd.BusinessMQ ## 业务消息队列 ##业务消 ...
- 【原创经验分享】WCF之消息队列
最近都在鼓捣这个WCF,因为看到说WCF比WebService功能要强大许多,另外也看了一些公司的招聘信息,貌似一些中.高级的程序员招聘,都有提及到WCF这一块,所以,自己也关心关心一下,虽然目前工作 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- Java消息队列--ActiveMq 实战
1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...
- Java消息队列--JMS概述
1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- [数据结构]——链表(list)、队列(queue)和栈(stack)
在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...
随机推荐
- x264代码剖析(三):主函数main()、解析函数parse()与编码函数encode()
x264代码剖析(三):主函数main().解析函数parse()与编码函数encode() x264的入口函数为main().main()函数首先调用parse()解析输入的參数,然后调用encod ...
- kibana中信息分类查询显示的方法
1.什么是kibana? kibana是ELK(elasticsearch+logstash+kibana)中的K,它是一个可灵活的分析和可视化平台,主要是显示数据以及根据这些数据绘出一些可视化图表, ...
- diff命令具体解释
diff命令參数: diff - 找出两个文件的不同点 总览 diff [选项] 源文件 目标文件 以下是 GNU所接受的 diff 的全部选项的概要. 大多数的选项有两个同样的名字,一个是单个的跟在 ...
- 1.namesapce用法
namespace用法示例 #include <iostream> using namespace std; //定义域名空间 namespace myspace { ; void sho ...
- metabase实施文档
安装提前:需要安装JDK1.8以上 软件下载地址: https://metabase.com 还需要下载 ojdbc7.jar,以支持Oracle驱动 下载地址:http://www.oracle.c ...
- GO语言学习(二十)Go 语言递归函数
Go 语言递归函数 递归,就是在运行的过程中调用自己. 语法格式如下: func recursion() { recursion() /* 函数调用自身 */ } func main() { recu ...
- Java Web学习总结(16)——JSP的九个内置对象
一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...
- ArcGIS教程:地理处理服务演示样例(河流网络)(三)
设置输出符号系统 步骤: 展开 StoweStreamNet.tbx 并双击创建河流网络模型. 接受默认的 45 公顷并单击确定以运行模型. StreamNet 图层将加入至 ArcMap. 右键单击 ...
- 重新启动IIS不重启电脑
有时候我们在WEB程序如:ASP,中无意中使用到了一个死循环,或者在测试 DLL组件时,挂了.这时候IIS就停止了响应,我们要继续我们的工作啊,重启IIS服务吧. 然而这个进程还在执行,Inter ...
- python课程:python3函数
摘自廖雪峰的网站:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014316 ...