在Linq lambda表达式中生成任务数组时,请使用Smaphoreslim



我正在使用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();
        }
    }

我的示例代码确实完成了我的意图。使用任务内部的信号量不会引起任何问题。它阻止了任务运行,这是目标。

最新更新