前言
在多线程和并发编程中,同步机制是不可或缺的,它帮助我们控制对共享资源的访问,以及管理线程间的协作。C#提供了多种同步原语,其中SemaphoreSlim是一个轻量级的同步原语,用于控制访问有限数量的资源。本文将深入探讨SemaphoreSlim的特点、构造函数、常用方法,并通过实例来展示其用法。
SemaphoreSlim简介
SemaphoreSlim是.NET Framework中System.Threading命名空间下的一个类,它提供了一个信号量机制,允许多个线程同时访问一定数量的资源。与Semaphore类相比,SemaphoreSlim是一个更轻量级的版本,专为需要高性能的场景设计,它主要适用于任务和异步编程。
SemaphoreSlim的特点
轻量级:SemaphoreSlim提供了一个简单而高效的信号量机制,相较于Semaphore,它在性能上有所优化,特别是在同一进程内部使用时。
灵活性:支持同步和异步的等待操作,使得它在异步编程中非常有用。
限制并发访问:可以限制对共享资源或共享操作的并发访问数量,从而实现对资源的有效管理。
SemaphoreSlim的构造函数
SemaphoreSlim提供了三个构造函数:
1、SemaphoreSlim(int initialCount):初始化SemaphoreSlim的实例,设置初始的信号量计数。
2、SemaphoreSlim(int initialCount, int maxCount):初始化SemaphoreSlim的实例,设置初始的信号量计数和最大信号量计数。
3、SemaphoreSlim(int initialCount, int maxCount, CancellationToken cancellationToken):此构造函数不存在。SemaphoreSlim不直接在构造函数中支持CancellationToken,但其WaitAsync方法支持。
SemaphoreSlim的常用方法
Wait和WaitAsync:请求进入信号量,如果当前计数大于0,则进入并将计数减1;如果计数为0,则等待直到其他线程释放信号量。
Release:释放信号量,将计数增加指定的值。
Dispose:释放SemaphoreSlim使用的所有资源。
使用 SemaphoreSlim 控制访问
基本用法
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static SemaphoreSlim semaphoreSlim =
new SemaphoreSlim(3);
// 最多允许3个线程同时访问
static void AccessDatabase(string name,
int seconds)
{
Console.WriteLine($"{name}
waits to access a database.");
semaphoreSlim.Wait();
Console.WriteLine($"{name}
is accessing the database.");
Thread.Sleep(TimeSpan
.FromSeconds(seconds));
// 模拟数据库访问
Console.WriteLine($"{name} is done.");
semaphoreSlim.Release();
}
static void Main(string[] args)
{
for (int i = 1; i <= 5; i++)
{
int id = i;
Task.Run(() =>
AccessDatabase($"Task {id}", id));
}
Console.ReadLine();
}
}
这个例子创建了一个SemaphoreSlim实例,允许最多3个线程同时访问数据库。通过Wait和Release方法,我们控制了对数据库访问的并发数。
异步用法
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(3);
// 最多允许3个任务同时执行
static async Task
AccessResourceAsync(string name, int seconds)
{
Console.WriteLine($"{name}
waits to access a resource.");
await semaphoreSlim.WaitAsync();
Console.WriteLine($"{name}
is accessing the resource.");
await Task.Delay
(TimeSpan.FromSeconds(seconds));
// 模拟异步操作
Console.WriteLine($"{name}
is done.");
semaphoreSlim.Release();
}
static async Task Main
(string[] args)
{
Task[] tasks = new Task[5];
for (int i = 1; i <= 5; i++)
{
int id = i;
tasks[i - 1] =
AccessResourceAsync($"Task {id}", id);
}
await Task.WhenAll(tasks);
Console.WriteLine("All
tasks have been completed.");
}
}
在这个异步示例中,我们使用WaitAsync方法替代了Wait方法,以非阻塞的方式等待信号量。这对于异步编程场景特别有用,因为它避免了在等待时阻塞线程。
总结
SemaphoreSlim是C#中一个非常有用的同步原语,它提供了一种高效的方式来控制对共享资源的并发访问。通过上述示例,我们可以看到SemaphoreSlim在同步和异步编程中的应用。掌握SemaphoreSlim的使用,对于开发高效、可靠的多线程和异步应用程序至关重要。
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。
也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!
优秀是一种习惯,欢迎大家留言学习!
作者:技术老小子
出处:mp.weixin.qq.com/s/cGacywr93XrxUXVn5th6EA
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!