如果我将maxConcurrency作为10传递,下面的代码会将最大并行任务限制为10吗?如何验证一次运行的任务数量?
public BlockingCollection<Task> _workTaskQueue;
public void DequeueTask(int maxConcurrency)
{
var tasks = new List<Task>();
using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency))
{
foreach (var task in _workTaskQueue.GetConsumingEnumerable())
{
concurrencySemaphore.Wait();
if (!(task.IsCanceled) && task.Status == TaskStatus.Created)
{
task.ContinueWith((t) => { concurrencySemaphore.Release(); });
tasks.Add(task);
task.Start();
}
}
}
Task.WaitAll(tasks.ToArray());
}
答案 0 :(得分:1)
由于您使用my other answer改变了逻辑,我为您准备了一个测试代码。 (不需要var tasks = new List<Task>();
)
Random rnd = new Random();
int maxConcurrency = 5;
var _workTaskQueue = new System.Collections.Concurrent.BlockingCollection<Task>();
for (int i = 0; i < 250; i++)
{
//Tasks running 250=500ms
_workTaskQueue.Add(new Task(()=> { Task.Delay(250 + rnd.Next(250)).Wait(); }));
}
_workTaskQueue.CompleteAdding();
int runningTaks = 0;
using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency))
{
foreach (var task in _workTaskQueue.GetConsumingEnumerable())
{
Console.WriteLine("LoopStart: " + runningTaks);
await concurrencySemaphore.WaitAsync();
Console.WriteLine("GotASem : " + runningTaks);
task.Start();
Interlocked.Increment(ref runningTaks);
task.ContinueWith(t =>
{
Interlocked.Decrement(ref runningTaks);
concurrencySemaphore.Release();
});
if (runningTaks > maxConcurrency) throw new Exception("ERROR");
Console.WriteLine("LoopEnd : " + runningTaks + Environment.NewLine);
}
Console.WriteLine("Finalizing: " + runningTaks);
//Make sure all all tasks have ended.
for (int i = 0; i < maxConcurrency; i++)
{
await concurrencySemaphore.WaitAsync();
}
Console.WriteLine("Finished: " + runningTaks);
}
答案 1 :(得分:0)
没有。缺少呼叫等待(进入互斥区块)。