我有一个队列奏效的方法。在消耗队列中的第一个对象之后,它会进入睡眠状态一段预定的时间(比如10秒)。如果队列在第三或第四秒被任何其他线程修改,是否有办法唤醒该线程?从休眠模式唤醒线程了,当一个集合被修改
回答
谢谢大家对你的建议的选项。我终于在这个需求上解决了AutoResetEvent。在消耗队列中的第一个对象之后,我不会将主线程设置为Sleep,而是从主线程中派生出一个新线程,并在那里调用sleep。主线只会等待。一旦新线程唤醒,它将使用Set信号通知主线程,主线程将恢复。这是一部分。
第二部分 - 如果任何其他线程修改队列,那么即使该线程也会在同一个EventWaitHandle上调用Set,从而再次使主线程恢复。
这可能不是最佳解决方案,但比其他方法更简单。
您应该使用专门为这样的目的而设计的集合。其中一个例子是BlockingCollection
,它允许您从集合中获取物品,并且如果没有物品可用,该方法将会阻塞,直到有物品提供给您。它也是一个专门设计用于从多个线程操纵的集合,缓解了同步的负担。
注意BlockingCollection
可以使之与不同类型的集合的支持初始化。默认情况下,它会使用一个ConcurrentQueue
,但也有在System.Collections.Concurrent
命名空间,如果你不想排队语义(好像你这样做虽然),您可以使用其他集合。如果你确实需要一些独特的东西,你也可以实现你自己的收集实现IProducerConsumerCollection<T>
。
我会把线程进入一个while
迭代,然后睡眠时间减少到像200毫秒。
但在每次迭代我会检查队列是否被修改。 通过这种方式,线程始终处于睡眠模式,并在队列被修改时唤醒。
当您想要停止线程时,您只需将while
条件设置为false
。
而不是Thread.Sleep
:
可以使用Monitor.Wait
有超时,您可以使用Monitor.Pulse
唤醒它,如果你从任何线程需要。
在任何情况下,我建议更换不使用Thread.Sleep()
因为它可以阻止完全线程。
这是更好的使用AutoResetEvent
或ManualResetEvent
到两个或多个线程同步:
https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx
Servy有这个使用Blocking Collection正确的答案。
只需进一步添加:当“工作”项在队列中可用并在该线程上异步处理它时,它会创建一个新的线程池线程。
你可以在一个生产者/消费者队列使用一个:
例如为:
/// <summary>
/// Producer/consumer queue. Used when a task needs executing, it’s enqueued to ensure order,
/// allowing the caller to get on with other things. The number of consumers can be defined,
/// each running on a thread pool task thread.
/// Adapted from: http://www.albahari.com/threading/part5.aspx#_BlockingCollectionT
/// </summary>
public class ProducerConsumerQueue : IDisposable
{
private BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();
public ProducerConsumerQueue(int workerCount)
{
// Create and start a separate Task for each consumer:
for (int i = 0; i < workerCount; i++)
{
Task.Factory.StartNew(Consume);
}
}
public void Dispose()
{
_taskQ.CompleteAdding();
}
public void EnqueueTask(Action action)
{
_taskQ.Add(action);
}
private void Consume()
{
// This sequence that we’re enumerating will block when no elements
// are available and will end when CompleteAdding is called.
// Note: This removes AND returns items from the collection.
foreach (Action action in _taskQ.GetConsumingEnumerable())
{
// Perform task.
action();
}
}
}
- 1. 唤醒睡眠线程
- 2. Scala:唤醒睡眠线程
- 3. 当Windows从睡眠模式唤醒时启动应用程序
- 4. 从另一个线程唤醒
- 5. 睡眠模式下USB总线如何从机唤醒主机
- 6. 从睡眠或休眠模式进入/唤醒时,Windows服务如何表现?
- 7. 睡眠一个过程,并唤醒它
- 8. 在C中唤醒休眠线程的剩余时间#
- 9. 如何唤醒睡眠(3)ing线程
- 10. 唤醒线程和退出睡眠
- 11. C# - 如何唤醒睡眠线程?
- 12. 使用从线程唤醒睡眠主线程
- 13. 线程调度模拟:正确的唤醒方式和睡眠线程
- 14. 如何在Android中唤醒一个线程睡眠
- 15. 休眠线程安全集合
- 16. 在Windows中以编程方式从待机/休眠中唤醒在python中?
- 17. WPF应用程序:唤醒计算机从睡眠或休眠状态
- 18. 如何唤醒C#.net中另一个线程的睡眠线程?
- 19. 当事件发生时唤醒线程
- 20. 线程 - 同步和睡眠线程拒绝唤醒(LINUX)
- 21. 唤醒睡眠线程,否则睡眠N秒
- 22. 如何确定设备是否已从睡眠模式内部被唤醒onResume
- 23. 从睡眠模式唤醒时运行脚本android X86
- 24. iBeacon检测通过UILocalNotification从睡眠模式唤醒iPhone
- 25. 在睡眠模式下从服务中唤醒Android Wear?
- 26. 从睡眠模式唤醒时音频不会播放(android)
- 27. 如何唤醒内核中的用户模式睡眠进程?
- 28. 多线程修改集合
- 29. 从休眠状态中唤醒时打开窗口
- 30. 通知从休眠状态C#唤醒时
你是什么意思的“去睡觉”?你使用Thread.Sleep方法或其他东西? – Fabjan
是的。我正在使用Thread.Sleep方法。 – Ganesh
是的,将您的收藏改为'System.Collections.Concurrent.BlockingCollection' –