多线程添加元素到队列中,队列根据绑定

的事件进行自动处理,可以设置WorkSequential属性来实现对队列处理的单线程(严格顺序处理)或者多线程处理(循序出队,但是

多线程处理,不保证对队列元素的处理顺利)的选择。

另外,这段程序不能输出0,所以,最后的结果是999行,不包含0,原因是if (!item.Equals(default(T))),而default(T)恰恰是0.

代码

/***********多线程的工作队列***************
* 此工作队列保证线程安全性
*
*
*
*
* *******/
namespace WorkQueue
{
using System.Collections.Generic;
using System;
using System.Threading; public delegate void UserWorkEventHandler<T>(object sender, WorkQueue<T>.EnqueueEventArgs e);
public class WorkQueue<T>
{
private bool IsWorking; //表明处理线程是否正在工作
private object lockIsWorking = new object();//对IsWorking的同步对象 private Queue<T> queue; //实际的队列
private object lockObj = new object(); //队列同步对象 /// <summary>
/// 绑定用户需要对队列中的item对象
/// 施加的操作的事件
/// </summary>
public event UserWorkEventHandler<T> UserWork; public WorkQueue(int n)
{
queue = new Queue<T>(n);
} public WorkQueue()
{
queue = new Queue<T>();
} /// <summary>
/// 谨慎使用此函数,
/// 只保证此瞬间,队列值为空
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
lock (lockObj)
{
return queue.Count == ;
}
} private bool isOneThread; /// <summary>
/// 队列处理是否需要单线程顺序执行
/// ture表示单线程处理队列的T对象
/// 默认为false,表明按照顺序出队,但是多线程处理item
/// *****注意不要频繁改变此项****
/// </summary>
public bool WorkSequential
{
get
{
return isOneThread;
}
set
{
isOneThread = value;
} } /// <summary>
/// 向工作队列添加对象,
/// 对象添加以后,如果已经绑定工作的事件
/// 会触发事件处理程序,对item对象进行处理
/// </summary>
/// <param name="item">添加到队列的对象</param>
public void EnqueueItem(T item)
{
lock (lockObj)
{
queue.Enqueue(item);
} lock (lockIsWorking)
{
if (!IsWorking)
{
IsWorking = true;
ThreadPool.QueueUserWorkItem(doUserWork);
}
} } /// <summary>
/// 处理队列中对象的函数
/// </summary>
/// <param name="o"></param>
private void doUserWork(object o)
{
try
{
T item; while (true)
{
lock (lockObj)
{
if (queue.Count > )
{
item = queue.Dequeue();
}
else
{
return;
}
}
if (!item.Equals(default(T)))
{ if (isOneThread)
{
if (UserWork != null)
{
UserWork(this, new EnqueueEventArgs(item));
}
}
else
{
ThreadPool.QueueUserWorkItem(obj =>
{
if (UserWork != null)
{
UserWork(this, new EnqueueEventArgs(obj));
}
}, item);
} } }
}
finally
{
lock (lockIsWorking)
{
IsWorking = false;
} }
} /// <summary>
/// UserWork事件的参数,包含item对象
/// </summary>
public class EnqueueEventArgs : EventArgs
{
public T Item { get; private set; }
public EnqueueEventArgs(object item)
{
try
{
Item = (T)item;
}
catch (Exception)
{ throw new InvalidCastException("object to T 转换失败");
}
}
}
}
}
代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using WorkQueue;
namespace Program
{
class Program
{
private static List<string> list=new List<string>();
static StreamWriter sw = new StreamWriter(new FileStream("test.dat", FileMode.Create));
static void Main(string[] args)
{
WorkQueue<int> workQueue=new WorkQueue<int>();
workQueue.UserWork += new UserWorkEventHandler<int>(workQueue_UserWork);
// workQueue.WorkSequential = true;
ThreadPool.QueueUserWorkItem(o =>
{
for (int i = ; i < ; i++)
{
workQueue.EnqueueItem(i); }
});
Console.ReadLine(); list.ForEach(str=>sw.WriteLine(str));
Console.WriteLine(workQueue.IsEmpty());
sw.Close();
} static void workQueue_UserWork(object sender, WorkQueue<int>.EnqueueEventArgs e)
{ StringBuilder sb=new StringBuilder();
sb.Append(e.Item).Append("\t\t").Append(DateTime.Now.ToString("u")+"\t\t").Append(Thread.CurrentThread.ManagedThreadId);
list.Add(sb.ToString());
Thread.Sleep();
}
}
}

一个C#多线程的工作队列的更多相关文章

  1. 一个关于多线程和DbHelper的问题

    我的初衷是这样的:在多线程环境下,每个数据库编号对应一个DbHelper对象. 下面是代码,不知道这样写有什么问题. namespace TestDAL { public class DB { pri ...

  2. 基于c++11新标准开发一个支持多线程高并发的网络库

    背景 新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间. 之前我也写过基于ACE的网络server框架,但A ...

  3. 编译一个支持多线程的php安装包

    前言 因为项目上的需要,需要用到php,一般来说,用默认的版本和配置就可以满足大多数的场景,因为需要加入多线程,所以需要自己编译一个包 一般来说,发行的包的版本的配置选项和代码都是最稳定的,所以在大多 ...

  4. 一个java多线程面试题

    线程a 打印 数字 0--12: 线程b 打印 字母 a--z; 打印结果:0ab1cd2ef3gh4ij5kl6mn7op8qr9st10uv11wx12yz 要求用到 线程间传值: 分析:线程a打 ...

  5. ios 多线程开发(一)简介

    简介 线程是在一个程序中并发的执行代码的方法之一.虽然有一些新的技术(operations, GCD)提供了更先进高效的并发实现,OS X和iOS同时也提供了创建和维护线程的接口. 这里将要介绍线程相 ...

  6. .NET进阶篇06-async异步、thread多线程2

    知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 内容目录 一.线程Thread1.生命周期2.后台线程3.静态方法1.线程本地存储2.内存栅栏4.返回值二.线程池ThreadPool1.工作队 ...

  7. Java 并发系列之四:java 多线程

    1. 线程简介 2. 启动和终止线程 3. 对象及变量的并发访问 4. 线程间通信 5. 线程池技术 6. Timer定时器 7. 单例模式 8. SimpleDateFormat 9. txt ja ...

  8. Java多线程中的wait/notify通信模式

    前言 最近在看一些JUC下的源码,更加意识到想要学好Java多线程,基础是关键,比如想要学好ReentranLock源码,就得掌握好AQS源码,而AQS源码中又有很多Java多线程经典的一些应用:再比 ...

  9. 在Parallel中使用DbSet.Add()发现的一系列多线程问题和解决过程

    发现问题 需求很简单,大致就是要批量往数据库写数据,于是打算用Parallel并行的方式写入,希望能利用计算机多核特性加快程序执行速度.想的很美好,于是快速撸了类似下面的一串代码: using (va ...

随机推荐

  1. bzoj1655 [Usaco2006 Jan] Dollar Dayz 奶牛商店

    Description Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of to ...

  2. CSS3 新特性 开放字体格式WOFF

    疑问 上面这是虾米玩意?    \e806 是在自定义字体表中的字体位置.    好嘛 现在问题来了 WOFF里面是什么东西呢? 怎么才能看到? 用这个:FontCreatorPortable     ...

  3. WEB打印插件Lodop

    Lodop.C-Lodop使用说明及样例   Lodop(标音:劳道谱,俗称:露肚皮)是专业WEB控件,用它既可裁剪输出页面内容,又可用程序代码直接实现 复杂打印.控件功能强大,却简单易用,所有调用如 ...

  4. Shortest Word Distance 解答

    Question Given a list of words and two words word1 and word2, return the shortest distance between t ...

  5. c++智能指针《一》 auto_ptr

    转载http://www.cnblogs.com/gnagwang/archive/2010/11/19/1881811.html C++的auto_ptr auto_ptr所做的事情,就是动态分配对 ...

  6. 【多线程】--生产者消费者模式--Lock版本

    在JDK1.5发布后,提供了Synchronized的更优解决方案:Lock 和 Condition 我们使用这些新知识,来改进例子:[多线程]--生产者消费者模式--Synchronized版本 改 ...

  7. css_day5

  8. EffectiveC#03--用委托表示回调,用事件定义对外接口

    1.回调的场景:我给了儿子一个任务且他可以报告状态来(重复的)打断我.而我在等待他完成任务的每一个部份时不用阻塞我自己的进程.他可以在有重要(或者事件)状态报告时,可以定时的打断我,或者向我询求帮助 ...

  9. 是什么让我想到开发NFinal

    我是从01前开始就接触.net,那时.net还是1.0时代,很多东西都没有.后来.net出了2.0版本.从vs2005开始就使用Webform做网站.当时感觉.net能够拖来拖去,很厉害.参加工作后, ...

  10. Spring MVC中数据绑定(转)

    Spring MVC中数据绑定 比如Product有一个createTime属性,是java.util.Date类型.那么最简单的转型处理是,在SimpleFormController中覆盖initB ...