[英]Thread-safe queue with tasks
我在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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.