我正在使用linq lambda表达式生成一系列任务,并将它们添加到任务列表中。我想实现信号量以限制给定时间点的过程中的任务数。
这是代表我当前拥有的代码:
class Test {
private List<Task> tasks;
public void Start(){
tasks = new List<Task>();
AddTasks();
}
private void AddTasks(){
tasks.AddRange(
items
.Where(x => x.InProcess == false)
.Select( async (item) = > {
await DoWork(item);
})
.ToArray()
);
}
}
我想取得类似的东西:
class Test {
private List<Task> tasks;
private SemaphoreSlim semaphore ;
public void Start(){
tasks = new List<Task>();
semaphore = new SemaphoreSlim(5);
AddTasks();
}
private void AddTasks(){
tasks.AddRange(
items
.Where(x => x.InProcess == false)
.Select( async (item) = > {
await semaphore.AwaitAsync();
try
{
await DoWork(item);
}
catch (System.Exception)
{
throw;
}
finally {
semaphore.Release();
}
})
.ToArray()
);
}
}
,但我认为这不会正常工作,因为信号量在任务内部。如何将信号量作为LINQ查询的一部分来停止生成新任务,直到等待信号量?
您可以尝试此代码。它应该按照您的预期工作,但我没有尝试过。并且不要忘记完成await Task.WhenAll(tasks)
完成后,您需要获得结果。
private void AddTasks()
{
tasks.AddRange(items
.Where(x => x.InProcess == false)
.Select(AddTaskAsync)
.ToArray());
//later await Task.WhenAll(tasks);
}
private async Task AddTaskAsync(YourClass item)
{
await semaphore.WaitAsync();
try
{
await DoWork(item);
}
finally
{
semaphore.Release();
}
}
我的示例代码确实完成了我的意图。使用任务内部的信号量不会引起任何问题。它阻止了任务运行,这是目标。