【发布时间】:2011-05-07 19:10:11
【问题描述】:
注意:
我对我的问题进行了彻底的修改。您可以通过更改历史记录查看原始问题。
我需要一个“强大”的队列,它提供以下功能:
- 我对一组对象有一定的范围。这意味着 A 组、B 组、...将有自己的队列
- 我正在组范围线程中填充队列线程 A(生产者)
- 我正在读取组范围线程中的队列线程 B(消费者)
所以我会有以下场景:
- 队列中没有任何项目(因为作业是使用空的“目标组”调用的):线程 B 应该退出循环
- 队列中目前没有项目,因为线程 A 正在处理要排队的项目:线程 B 应该等待
- 队列中有项目:线程 B 应该能够出列并处理项目
- 队列中没有项目,因为 线程 A 没有更多要排队的项目:线程 B 应该退出循环
现在我想出了以下实现:
public class MightyQueue<T>
where T : class
{
private readonly Queue<T> _queue = new Queue<T>();
private bool? _runable;
private volatile bool _completed;
public bool Runable
{
get
{
while (!this._runable.HasValue)
{
Thread.Sleep(100);
}
return this._runable ?? false;
}
set
{
this._runable = value;
}
}
public void Enqueue(T item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
this._queue.Enqueue(item);
}
public void CompleteAdding()
{
this._completed = true;
}
public bool TryDequeue(out T item)
{
if (!this.Runable)
{
item = null;
return false;
}
while (this._queue.Count == 0)
{
if (this._completed)
{
item = null;
return false;
}
Thread.Sleep(100);
}
item = this._queue.Dequeue();
return true;
}
}
然后会被使用
制片人
if (anythingToWorkOn)
{
myFooMightyQueueInstance.Runable = false;
}
else
{
myFooMightyQueueInstance.Runable = true;
while (condition)
{
myFooMightyQueueInstance.Enqueue(item);
}
myFooMightyQueueInstance.CompleteAdding();
}
消费者
if (!myFooMightyQueueInstance.Runable)
{
return;
}
T item;
while (myFooMightyQueueInstance.TryDequeue(out item))
{
//work with item
}
但我相信,这种方法是错误的,因为我在那里使用了一些 Thread.Sleep()-stuff(不能有一些 waitHandle 或其他东西吗?)...我不是关于算法本身任何一个 ...
谁能帮帮我?
【问题讨论】:
-
那么,您的问题是什么,到目前为止您尝试过什么?听起来像是一个简单的 Two_Thread 结构,中间有一个队列,需要从线程 B 查询。
-
@marcelo:
just wondering how to fully solve this problem应该清楚 -
绝对没有理由在这种情况下使用线程,因为线程 B 只会等待线程 A,就像 90% 的时间一样 + 考虑到上下文切换开销和线程同步开销,结果可能很容易多线程版本实际上会比单线程版本慢
-
@psicho:我的问题不是性能,而是时间问题。如果您需要在例如开始邮寄。 08h00,您需要未知的时间来准备尸体(因为您不确切知道一个尸体的数量或所需时间),您始终可以选择开始,例如。提前5分钟准备。所以这就是多线程的原因!
-
@Andreas:可以将 SMTP 服务器配置为接受队列消息,允许您将线程卸载到邮件服务器。你在这里实现的东西已经解决了。
标签: c# multithreading .net-3.5 queue