我有一個隊列奏效的方法。在消耗隊列中的第一個對象之後,它會進入睡眠狀態一段預定的時間(比如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' –