我怎样才能确保只有一个线程会做某事?
我有多个线程将项目添加到无锁队列中。
然后这些项目由另一个线程处理。
在生产者线程中,我需要启动消费者线程,但前提是它尚未运行或启动。
具体来说:
public void BeginInvoke(Action method)
{
//This runs on multiple background threads
pendingActions.Enqueue(method);
if (ProcessQueue hasn't been posted)
uiContext.Post(ProcessQueue, null);
}
private void ProcessQueue(object unused)
{
//This runs on the UI thread.
Action current;
while (pendingActions.TryDequeue(out current))
current();
}
我使用的是.Net 3.5,而不是4.0。 :(
I have multiple threads which add items to a lock-free queue.
The items are then processed by another thread.
In the producer threads, I need to kick off the consumer thread, but only if it's not already running or kicked off.
Specifically:
public void BeginInvoke(Action method)
{
//This runs on multiple background threads
pendingActions.Enqueue(method);
if (ProcessQueue hasn't been posted)
uiContext.Post(ProcessQueue, null);
}
private void ProcessQueue(object unused)
{
//This runs on the UI thread.
Action current;
while (pendingActions.TryDequeue(out current))
current();
}
I'm using .Net 3.5, not 4.0. :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最简单的方法是使用信号量。它将有队列大小的计数。
The easiest way is to use
Semaphore
. It will have a count of queue size.我创建了以下类来执行此操作:
我像这样使用它:
此模式安全吗?
有更好的方法吗?
班级有更正确的名称吗?
I created the following class to do this:
I use it like this:
Is this pattern safe?
Is there a better way to do this?
Is there a more correct name for the class?
这对你有用吗?
Does this work for you?
创建第二个 调度程序< /a> 用于消费者线程。然后,生产者线程可以使用该调度程序的 BeginInvoke() 方法将数据发送到消费者线程。 Dispatcher 的队列取代了pendingActions 队列,并确保使用者线程一次仅处理一个工作项。
与其让生产者线程尝试协调消费者线程的启动和停止,不如在启动任何生产者之前启动消费者线程,并让它闲置。调度程序应该在需要时自动唤醒它。
Create a second Dispatcher for the consumer thread. Then, producer threads can use that dispatcher's BeginInvoke() method to send data to the consumer thread. The Dispatcher's queue takes the place of your pendingActions queue, and ensures that the consumer thread is only processing one work item at a time.
Rather than having the producer threads try to coordinate starting and stopping the consumer thread, just start the consumer thread before any producers have been started, and let it sit idle. The Dispatcher should automatically take care of waking it up when needed.