c# 多线程排队队列实现的源码
来源:互联网 发布:java守护线程有什么用 编辑:程序博客网 时间:2024/05/29 13:38
using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
// 将线程同步事件封装在此类中,
// 以便于将这些事件传递给 Consumer 和
// Producer 类。
public class SyncEvents
{
public SyncEvents()
{
// AutoResetEvent 用于“新项”事件,因为
// 我们希望每当使用者线程响应此事件时,
// 此事件就会自动重置。
_newItemEvent = new AutoResetEvent(false);
// ManualResetEvent 用于“退出”事件,因为
// 我们希望发出此事件的信号时有多个线程响应。
// 如果使用 AutoResetEvent,事件
// 对象将在单个线程作出响应之后恢复为
// 未发信号的状态,而其他线程将
// 无法终止。
_exitThreadEvent = new ManualResetEvent(false);
// 这两个事件也放在一个 WaitHandle 数组中,以便
// 使用者线程可以使用 WaitAny 方法
// 阻塞这两个事件。
_eventArray = new WaitHandle[2];
_eventArray[0] = _newItemEvent;
_eventArray[1] = _exitThreadEvent;
}
// 公共属性允许对事件进行安全访问。
public EventWaitHandle ExitThreadEvent
{
get { return _exitThreadEvent; }
}
public EventWaitHandle NewItemEvent
{
get { return _newItemEvent; }
}
public WaitHandle[] EventArray
{
get { return _eventArray; }
}
private EventWaitHandle _newItemEvent;
private EventWaitHandle _exitThreadEvent;
private WaitHandle[] _eventArray;
}
// Producer 类(使用一个辅助线程)
// 将项异步添加到队列中,共添加 20 个项。
public class Producer
{
public Producer(Queue<int> q, SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
public void ThreadRun()
{
int count = 0;
Random r = new Random();
while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
{
lock (((ICollection)_queue).SyncRoot)
{
while (_queue.Count < 20)
{
_queue.Enqueue(r.Next(0, 100));
_syncEvents.NewItemEvent.Set();
count++;
}
}
}
Console.WriteLine("Producer thread: produced {0} items", count);
}
private Queue<int> _queue;
private SyncEvents _syncEvents;
}
// Consumer 类通过自己的辅助线程使用队列
// 中的项。Producer 类使用 NewItemEvent
// 将新项通知 Consumer 类。
public class Consumer
{
public Consumer(Queue<int> q, SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
public void ThreadRun()
{
int count = 0;
while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
{
lock (((ICollection)_queue).SyncRoot)
{
int item = _queue.Dequeue();
}
count++;
}
Console.WriteLine("Consumer Thread: consumed {0} items", count);
}
private Queue<int> _queue;
private SyncEvents _syncEvents;
}
public class ThreadSyncSample
{
private static void ShowQueueContents(Queue<int> q)
{
// 对集合进行枚举本来就不是线程安全的,
// 因此在整个枚举过程中锁定集合以防止
// 使用者和制造者线程修改内容
// 是绝对必要的。(此方法仅由
// 主线程调用。)
lock (((ICollection)q).SyncRoot)
{
foreach (int i in q)
{
Console.Write("{0} ", i);
}
}
Console.WriteLine();
}
static void Main()
{
// 配置结构,该结构包含线程同步
// 所需的事件信息。
SyncEvents syncEvents = new SyncEvents();
// 泛型队列集合用于存储要制造和使用的
// 项。此例中使用的是“int”。
Queue<int> queue = new Queue<int>();
// 创建对象,一个用于制造项,一个用于
// 使用项。将队列和线程同步事件传递给
// 这两个对象。
Console.WriteLine("Configuring worker threads...");
Producer producer = new Producer(queue, syncEvents);
Consumer consumer = new Consumer(queue, syncEvents);
// 为制造者对象和使用者对象创建线程
// 对象。此步骤并不创建或启动
// 实际线程。
Thread producerThread = new Thread(producer.ThreadRun);
Thread consumerThread = new Thread(consumer.ThreadRun);
// 创建和启动两个线程。
Console.WriteLine("Launching producer and consumer threads...");
producerThread.Start();
consumerThread.Start();
// 为制造者线程和使用者线程设置 10 秒的运行时间。
// 使用主线程(执行此方法的线程)
// 每隔 2.5 秒显示一次队列内容。
for (int i = 0; i < 4; i++)
{
Thread.Sleep(2500);
ShowQueueContents(queue);
}
// 向使用者线程和制造者线程发出终止信号。
// 这两个线程都会响应,由于 ExitThreadEvent 是
// 手动重置的事件,因此除非显式重置,否则将保持“设置”。
Console.WriteLine("Signaling threads to terminate...");
syncEvents.ExitThreadEvent.Set();
// 使用 Join 阻塞主线程,首先阻塞到制造者线程
// 终止,然后阻塞到使用者线程终止。
Console.WriteLine("main thread waiting for threads to finish...");
producerThread.Join();
consumerThread.Join();
}
}
namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
public delegate void Delegate1();
public delegate void Delegate2(DataTable dt);
public void buttonFind_Click(object sender, EventArgs e)
{
Delegate1 d1 = new Delegate1(Find);
d1.BeginInvoke(new AsyncCallback(AsyncCallback1), d1);
}
public void AsyncCallback1(IAsyncResult iAsyncResult)
{
Delegate1 d1 = (Delegate1)iAsyncResult.AsyncState;
d1.EndInvoke(iAsyncResult);
}
public void Find()
{
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("age", typeof(int));
AddRow(dt, "张三", 19);
AddRow(dt, "张三", 19);
AddRow(dt, "李四", 18);
this.Invoke(new Delegate2(Bind2), new object[] { dt });
}
public void AddRow(DataTable dt, string name, int age)
{
DataRow dr = dt.NewRow();
dr["name"] = name;
dr["age"] = age;
dt.Rows.Add(dr);
}
public void Bind2(DataTable dt)
{
this.dataGridView1.DataSource = dt;
}
}
}
- c# 多线程排队队列实现的源码
- 一个C#多线程的工作队列 ,c# 多线程排队队列实现的源码
- C# 【多线程+队列】【附源码】 实现右下角的消息提示框,支持同时显示多个提示框
- c# 多线程 生产者/消费者队列 源码
- 队列实现最简单的排队看病系统
- 多线程 线程队列的实现
- c++多线程队列的实现
- C#多线程的实现
- 队列的链式实现源码
- 一个C#多线程的工作队列
- 一个C#多线程的工作队列
- 一个C#多线程的工作队列
- 链队列实现病人排队看病
- COM+队列的C#实现
- 多线程读取循环队列的实现
- c++ 多线程阻塞队列的简单实现
- java多线程消息队列的实现
- java多线程:消息队列的实现
- Ubuntu下轻量快速的文件管理器-PCMan
- 准备博客搬家(已经成功)
- msdn中 wpf serverlet asp.net 等等 下载各种控件样式 风格
- EXT4.0 (1~3章)学习内容
- Flex最佳实践
- c# 多线程排队队列实现的源码
- android动画实现-Frame animation(一)
- 物理dataguard 正常切换 脚色转换,switchover_status 状态改变
- java ssh mysql实现文件上传下载功能
- Android类参考---Looper
- 证书链验证时出现异常:Signature does not match解决办法
- 【android开发】之【android动态布局方法总结】
- 泛型类:Queue
- 网络编程--IO模型示例