我正在使用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查询中使用信号灯来停止生成新任务,直到等待信号灯?
答案 0 :(得分:0)
您可以尝试使用此代码。它应该可以按照您的预期工作,但是我还没有尝试过。并且不要忘了在完成操作后致电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();
}
}
答案 1 :(得分:-1)
我的示例代码确实达到了我的预期。在Task内部使用信号灯不会引起任何问题。它阻止了任务的运行,这是目标。