在C#中,处理并发操作是一项常见且强大的功能,特别是在需要执行多个任务但又想限制同时运行任务数量的场景中。过多的并发任务可能会耗尽系统资源,导致性能下降。因此,合理控制并发任务的数量是至关重要的。本文将介绍几种在C#中限制并发任务数量的方法,并提供相关应用场景和示例代码。
SemaphoreSlim
是一个轻量级的同步原语,用于控制访问某一资源或资源池的线程数。通过它,我们可以很容易地限制并发任务的数量。
当你有一个需要访问共享资源(如数据库连接池)的任务列表,但希望同时执行的任务数量不超过某个特定值时,可以使用 SemaphoreSlim
。
C#using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
int maxConcurrentTasks = 3;
SemaphoreSlim semaphore = new SemaphoreSlim(maxConcurrentTasks);
List<Task> tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
await semaphore.WaitAsync();
var task = Task.Run(async () =>
{
try
{
// 模拟长时间运行的任务
Console.WriteLine($"Task {Task.CurrentId} started.");
await Task.Delay(TimeSpan.FromSeconds(2));
Console.WriteLine($"Task {Task.CurrentId} completed.");
}
finally
{
semaphore.Release();
}
});
tasks.Add(task);
}
await Task.WhenAll(tasks);
Console.WriteLine("All tasks completed.");
}
}
在这个示例中,我们限制了最多只有3个任务可以同时运行。通过对 SemaphoreSlim
的调用,我们确保了当达到最大并发任务数量时,其他任务将会等待直到某个任务完成并释放信号量。
TPL (Task Parallel Library) Dataflow 提供了一个更高级的方式来处理数据流和并发任务,通过它可以很容易地限制并发任务的数量。
当你需要处理一系列的数据或任务,并且每个任务都可能需要一些时间来完成,同时你想要限制同时处理这些任务的数量时,可以使用 TPL Dataflow。
C#using System;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
class Program
{
static async Task Main(string[] args)
{
var options = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 3 // 最大并发任务数量
};
var block = new ActionBlock<int>(async n =>
{
Console.WriteLine($"Processing {n}...");
await Task.Delay(TimeSpan.FromSeconds(1)); // 模拟异步操作
Console.WriteLine($"Processed {n}.");
}, options);
for (int i = 0; i < 100; i++)
{
block.Post(i);
}
block.Complete();
await block.Completion;
Console.WriteLine("All tasks completed.");
}
}
在这个示例中,ActionBlock
被用来处理一系列的任务,通过设置 ExecutionDataflowBlockOptions
中的 MaxDegreeOfParallelism
属性,我们限制了最大的并发任务数量。
限制并发任务的数量是确保应用程序稳定和高效运行的关键。在C#中,我们可以使用 SemaphoreSlim
或 TPL Dataflow 来轻松实现这一目标。根据你的具体需求和应用场景,选择最合适的方法来控制并发任务的数量。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!