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# 安全队列的更多相关文章

  1. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  2. 消息队列 Kafka 的基本知识及 .NET Core 客户端

    前言 最新项目中要用到消息队列来做消息的传输,之所以选着 Kafka 是因为要配合其他 java 项目中,所以就对 Kafka 了解了一下,也算是做个笔记吧. 本篇不谈论 Kafka 和其他的一些消息 ...

  3. Beanstalkd一个高性能分布式内存队列系统

    高性能离不开异步,异步离不开队列,内部是Producer-Consumer模型的原理. 设计中的核心概念: job:一个需要异步处理的任务,是beanstalkd中得基本单元,需要放在一个tube中: ...

  4. .net 分布式架构之业务消息队列

    开源QQ群: .net 开源基础服务  238543768 开源地址: http://git.oschina.net/chejiangyi/Dyd.BusinessMQ ## 业务消息队列 ##业务消 ...

  5. 【原创经验分享】WCF之消息队列

    最近都在鼓捣这个WCF,因为看到说WCF比WebService功能要强大许多,另外也看了一些公司的招聘信息,貌似一些中.高级的程序员招聘,都有提及到WCF这一块,所以,自己也关心关心一下,虽然目前工作 ...

  6. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  7. Java消息队列--ActiveMq 实战

    1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...

  8. Java消息队列--JMS概述

    1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...

  9. 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)

    Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...

  10. [数据结构]——链表(list)、队列(queue)和栈(stack)

    在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...

随机推荐

  1. BZOJ2243: [SDOI2011]染色(树链剖分/LCT)

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...

  2. LoadRunner IP欺骗使用

  3. [Python] The get() method on Python dicts and its "default" arg

    # The get() method on dicts # and its "default" argument name_for_userid = { 382: "Al ...

  4. WebSocket兼容到低版本浏览器

    就目前而言,WebSocket是最好的Web通信解决方案了.但是IE从10才开始兼容它,对于目前大量IE8存在的市场,原生的WebSocket显然不太实用,我们需要低版本兼容的解决方案.于是我模拟We ...

  5. 25.Spring @Transactional工作原理

    转自:http://www.importnew.com/12300.html 本文将深入研究Spring的事务管理.主要介绍@Transactional在底层是如何工作的.之后的文章将介绍: prop ...

  6. ANSI转UTF-8中文无乱码解决方案

    近期做的项目需要使用Doxygen生成文档,由于前期代码不是本人完成,他使用的是ANSI格式的文件,后来我用Notepad++写其他文件时,默认保存为UTF-8 无BOM编码格式,因此整个项目文件中既 ...

  7. Loadrunner--集合点

    集合点的意思是等到特定的用户数后再一起执行某个操作,比如一起保存,一起提交(我们通常意义上的并发数并不是指一起提交或者一起保存),一般情况下使用不到集合点,不过,订票系统或者促销类需要用到,比如说某个 ...

  8. echarts同一页面四个图表切换的js数据交互

    需求:点击tab页,切换四个不同的图表,ajax向后台请求数据,展示在四个不同的图表中. 其余的就不多说,直接上js代码了 $(function() { $("#heart").o ...

  9. Java BlockingQueue Example(如何使用阻塞队列实现生产者-消费者问题)

    Today we will look into Java BlockingQueue. java.util.concurrent.BlockingQueue is a java Queue that ...

  10. 利用朴素贝叶斯(Navie Bayes)进行垃圾邮件分类

    贝叶斯公式描写叙述的是一组条件概率之间相互转化的关系. 在机器学习中.贝叶斯公式能够应用在分类问题上. 这篇文章是基于自己的学习所整理.并利用一个垃圾邮件分类的样例来加深对于理论的理解. 这里我们来解 ...