我在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. 帶線程的線程安全隊列
- 2. 線程安全隊列 - 入隊/出隊
- 3. 帶有任務隊列問題的彈簧安全
- 4. STL隊列的線程安全
- 5. C++線程安全的隊列關機
- 6. 在C++中的線程安全隊列
- 7. Servlets中的線程安全和排隊任務
- 8. Java隊列和線程安全
- 9. 線程安全異步字節隊列
- 10. Azure Blob和隊列線程安全
- 11. 線程安全優先級隊列
- 12. 如何實現線程安全隊列
- 13. 線程安全隊列實現
- 14. LinkedList隊列和線程安全
- 15. 線程安全隊列映射
- 16. 線程安全隊列死鎖
- 17. 製作隊列線程安全
- 18. 大量的單線程任務隊列
- 19. 帶線程池的Java線程隊列
- 20. Android定時器任務線程安全
- 21. 使RxJava異步任務線程安全
- 22. 帶任務隊列的AppEngine超時
- 23. 線程安全傳遞整數到任務執行任務
- 24. java:組合多線程/單線程任務隊列
- 25. 如何使循環隊列完全線程安全
- 26. 多線程寫入,一個線程從隊列中讀取,線程安全
- 27. 帶有隊列的Python線程
- 28. Python安全隊列
- 29. ActiveMQ安全隊列
- 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