C#中如何控制缓冲空间的上限
2007-12-31 22:35
260 查看
我们用C#基于“生产者/消费者”编程时,往往会用Queue、Hashtable或 Dictionary 泛型类型来作一个缓存,用于缓存“生产者”产生的数据,若“消费者”能及时处理这些数据,倒不成问题,但若某种原因,导致“消费者”没有及时处理,就可能导致内存被大量消耗,系统性能急剧下降,直到失去响应。如何有效地限制缓冲空间的上限?由于我们的“生产者”与“消费者”可能分别为多个线程,因此不能采用简单加锁的方式来解决,而是使用ManualResetEvent 或AutoResetEvent来实现线程间的消息传递。 解决方案如下代码所示:
/// <summary>
/// 这个例子用于演示如例控制一个缓冲的大小
/// 此例中以一个队列为类,假定元素成员总数不得大于100个
/// </summary>
public class BufferManager
{
public Queue<int> buffer = new Queue<int>();
private System.Threading.ManualResetEvent ev = new System.Threading.ManualResetEvent(false);
/// <summary>
/// 将对象添加到 Queue 的结尾处,模拟生产者。 Queue 的容量是指 Queue 可以保存的元素数。随着向 Queue 中添加元素,容量通过重新分配按需自动增加。
/// 测试证明,如果不加限制地添加,可能会导致内存大量被占用,甚至系统停止响应
/// </summary>
/// <param name="item"></param>
public void Enqueue(int item)
{
if (buffer.Count > 99)
{
//若缓冲大于99个成员,则阻塞线程
ev.WaitOne();
}
lock (buffer)
{
buffer.Enqueue(item);
//向队列(缓冲)添加一个元素后,判断一下元素个数是否已达上限,若已达上限,则发出阻塞通知
if (buffer.Count > 99)
{
ev.Reset();
}
}
}
/// <summary>
/// 从 Queue 的开头移除的对象。模拟消费者。
/// </summary>
public void Dequeue()
{
if (buffer.Count > 0)
{
lock (buffer)
{
buffer.Dequeue();
//从队列(缓冲取出一个元素后,通知被阻塞的线程继续)
ev.Set();
}
}
}
}
/// <summary>
/// 这个例子用于演示如例控制一个缓冲的大小
/// 此例中以一个队列为类,假定元素成员总数不得大于100个
/// </summary>
public class BufferManager
{
public Queue<int> buffer = new Queue<int>();
private System.Threading.ManualResetEvent ev = new System.Threading.ManualResetEvent(false);
/// <summary>
/// 将对象添加到 Queue 的结尾处,模拟生产者。 Queue 的容量是指 Queue 可以保存的元素数。随着向 Queue 中添加元素,容量通过重新分配按需自动增加。
/// 测试证明,如果不加限制地添加,可能会导致内存大量被占用,甚至系统停止响应
/// </summary>
/// <param name="item"></param>
public void Enqueue(int item)
{
if (buffer.Count > 99)
{
//若缓冲大于99个成员,则阻塞线程
ev.WaitOne();
}
lock (buffer)
{
buffer.Enqueue(item);
//向队列(缓冲)添加一个元素后,判断一下元素个数是否已达上限,若已达上限,则发出阻塞通知
if (buffer.Count > 99)
{
ev.Reset();
}
}
}
/// <summary>
/// 从 Queue 的开头移除的对象。模拟消费者。
/// </summary>
public void Dequeue()
{
if (buffer.Count > 0)
{
lock (buffer)
{
buffer.Dequeue();
//从队列(缓冲取出一个元素后,通知被阻塞的线程继续)
ev.Set();
}
}
}
}
相关文章推荐
- C# 文本框如何控制只能输入数字?
- C#中如何控制播放音乐的声音大小
- 如何控制QQ好友访问空间?
- 看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制
- C# 如何获取磁盘剩余空间
- C#中如何实现传值控制led屏显内容
- 如何清除linux的内存缓存,缓冲和交换空间
- ASP.NET C# 如何在程序中控制IIS服务或应用程序池重启?
- 【C#】如何获取Dropdownlist空间已知值对应的Index,实现查询Dropdownlist值
- 如何在C#中调用C++或者VB中的命名空间
- 如何控制C#引用DLL的位置
- 如何优雅的控制C#的线程
- c# 线程中如何控制控件焦点
- C#.NET常见问题(FAQ)-命名空间namespace如何理解
- C# richTextBox如何控制行高的问题
- 如何控制C#Socket的连接超时时间
- WinForm中DataGrid(C#)应用 - 如何控制DataGrid显示规定行数.
- ASP.NET C# 如何在程序中控制IIS服务或应用程序池重启?
- C#如何控制方法的执行时间,超时则强制退出方法执行
- C# 给某个方法设定执行超时时间 C#如何控制方法的执行时间,超时则强制退出方法执行 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)