我在c#中有一些工作管理器,它將接收任務並執行它們。任務將從不同的線程到達,但它們必須按照它們接收的順序同時執行一個。 我不想要一個while循環,它將一直運行,檢查它們是否是隊列中的新任務。是否有內置隊列或簡單的方法來實現隊列,該隊列將等待任務並同步執行而不需要等待?帶任務的線程安全隊列
回答
按照該意見,你應該考慮ConcurrentQueue也BlockingCollection和使用GetConsumingEnumerable(),而不是你不想要的WHILE循環
BlockingCollection<YourClass> _collection =
new BlockingCollection<YourClass>(new ConcurrentQueue<YourClass>());
_collection.Add() can be called from multiple threads
在一個單獨的線程可以使用
foreach (var message in _collection.GetConsumingEnumerable())
{}
請求是在同一時間做一個 –
他的判決不明確,「但他們必須同時執行一個」。我假設他希望他們以順序方式一次執行一個 –
「但它們必須同時執行**只有一個**」 –
你可以使用SemaphoreSlim(https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx)和ConcurrentQueue
示例:
private delegate void TaskBody();
private class TaskManager
{
private ConcurrentQueue<TaskBody>
TaskBodyQueue = new ConcurrentQueue<TaskBody>();
private readonly SemaphoreSlim
TaskBodySemaphoreSlim = new SemaphoreSlim(1, 1);
public async void Enqueue(TaskBody body)
{
TaskBodyQueue.Enqueue(body);
await TaskBodySemaphoreSlim.WaitAsync();
Console.WriteLine($"Cycle ...");
if (TaskBodyQueue.TryDequeue(out body) == false) {
throw new InvalidProgramException($"TaskBodyQueue is empty!");
}
body();
Console.WriteLine($"Cycle ... done ({TaskBodyQueue.Count} left)");
TaskBodySemaphoreSlim.Release();
}
}
public static void Main(string[] args)
{
var random = new Random();
var tm = new TaskManager();
Parallel.ForEach(Enumerable.Range(0, 30), async number => {
await Task.Delay(100 * number);
tm.Enqueue(delegate {
Console.WriteLine($"Print {number}");
});
});
Task
.Delay(4000)
.Wait();
WaitFor(action: "exit");
}
public static void WaitFor(ConsoleKey consoleKey = ConsoleKey.Escape, string action = "continue")
{
Console.Write($"Press {consoleKey} to {action} ...");
var consoleKeyInfo = default(ConsoleKeyInfo);
do {
consoleKeyInfo = Console.ReadKey(true);
}
while (Equals(consoleKeyInfo.Key, consoleKey) == false);
Console.WriteLine();
}
謝謝。這看起來像一個很好的解決方案,但BlockingCollection對於這個問題似乎更簡單和簡單。 – user3126358
- 1. STL隊列的線程安全
- 2. C++線程安全的隊列關機
- 3. Servlets中的線程安全和排隊任務
- 4. 線程安全隊列映射
- 5. 線程安全隊列死鎖
- 6. 線程安全異步字節隊列
- 7. Azure Blob和隊列線程安全
- 8. java:組合多線程/單線程任務隊列
- 9. 如何使循環隊列完全線程安全
- 10. ActiveMQ安全隊列
- 11. 如何使使用隊列線程安全的異步方法
- 12. 這是使用靜態隊列線程安全的嗎?
- 13. Python:基於文件的線程安全隊列
- 14. 是否有Visual Studio C++ 6.0的線程安全隊列類?
- 15. Delphi的線程安全優先級隊列?
- 16. Swift:串行隊列中的線程安全計數器
- 17. 關於隊列和線程安全的查詢
- 18. 使用.each/iterator的線程安全Ruby隊列
- 19. 使用peek的線程安全可重入隊列
- 20. 不是ruby隊列線程安全爲什麼隊列不同步?
- 21. 扭曲CPU隊列任務的隊列
- 22. 列表線程安全嗎?
- 23. 線程安全陣列
- 24. VB.NET線程安全列表?
- 25. 取消線程中的任務執行並從隊列中刪除任務
- 26. 線程安全隊列<t>在C#
- 27. 將SQL 2008 ServiceBroker用於大容量線程安全FIFO隊列
- 28. Tomcat 6線程安全電子郵件隊列(javax.mail。*)
- 29. C++ 11事件循環與線程安全隊列
- 30. 線程安全隊列是一個好方法嗎?
我不認爲這是建立功能對於此模式,但你可以通過建立一個無while循環** ** SemaphoreSlim –
你檢查[ConcurrentQueue](https://msdn.microsoft.com/ en-us/library/dd267265(v = vs.110).aspx)和/或[Queue.Synchronized](https://msdn.microsoft.com/en-us/library/system.collections.queue.synchronized( v = vs.110)的.aspx)? –
Hintham
考慮到您的要求,它不會一直運行,TPL數據流是一種可行的方法。你可以控制它的執行方式(就線程而言),所以我認爲你應該能夠確保一次只運行一個。小心你不要創建積壓。 – john