C# 使用过多的信号量lim(N)来管理并发是否会影响性能?

C# 使用过多的信号量lim(N)来管理并发是否会影响性能?,c#,.net,.net-core,C#,.net,.net Core,问题: 我有一个HTTP客户端,它向天气预报系统发出请求。目前,对天气预报API的并发调用次数有限制。对于当前层,最大并发限制为每秒60次并发GET调用。但这一限制在未来可能会变为100200甚至更多 使用更多的信号量会影响性能吗 代码: 公共类WeatherApiWithConcurrencyAdapter { 私有只读WeatherForecastApi_WeatherForecastApi; private const int MaxConcurrencyPerSecond=60; 私有静

问题: 我有一个HTTP客户端,它向天气预报系统发出请求。目前,对天气预报API的并发调用次数有限制。对于当前层,最大并发限制为每秒60次并发GET调用。但这一限制在未来可能会变为100200甚至更多

使用更多的信号量会影响性能吗

代码

公共类WeatherApiWithConcurrencyAdapter
{
私有只读WeatherForecastApi_WeatherForecastApi;
private const int MaxConcurrencyPerSecond=60;
私有静态只读信号量LIM ConcurrencySemaphore=
新的信号量lim(maxconcurrentypersecond,maxconcurrentypersecond);
私有静态只读TimeSpan信号量ReleaseDelay=TimeSpan.FromSeconds(1);
带有并发适配器的公共天气预报器(WeatherForecastApi WeatherForecastApi)
{
_weatherForecastApi=weatherForecastApi;
}
公共异步任务GetWeatherForecastSync(WeatherForecastQuery查询)
{
//强制并发
wait concurrency.WaitAsync();
天气预报结果;
尝试
{
//调用天气预报API
结果=_weatherForecastApi.GetForecast(查询);
}
最后
{
//开火并忘记:
//用于此调用的信号量将在1秒后释放
任务延迟(信号量延迟)
.ContinueWith(=>ConcurrencySemaphore.Release())
.GetAwaiter();
}
返回结果;
}
}

让我们看看这行代码:

private static readonly SemaphoreSlim  ConcurrencySemaphore = 
                    new SemaphoreSlim(MaxConcurrencyPerSecond,MaxConcurrencyPerSecond);
声明之前的
static
表示只创建了一个
ConcurrencySemaphore
实例

因此,无论有多少并发客户机工作,都不会有问题。信号量只存储对客户端的引用,并提高/降低以最大值为界的计数。无论并发客户端的数量如何,信号量对象在性能方面保持不变

ConcurrencySemaphore
在任何给定时间允许运行的并发线程数都不会有问题

在以下情况下,您可能会有严重的延迟:

  • 考虑到有争议的代码需要大量的时间和资源来执行
  • 如果并行运行多个请求会使每个请求变慢,那么为下一个请求释放请求将需要更多时间
  • 这可能会为希望使用您的服务的客户端创建一个活锁情况
  • 更糟糕的是:

    如果多个线程被阻塞,则没有保证顺序(如FIFO或LIFO)来控制线程何时进入信号量


    这可能意味着长时间的等待可能会导致一些请求几乎无限期地等待。

    这里只有一个SemaphoreSlim实例,对吗?@MatthewWatson是的,这就是目的所在。不管创建了多少适配器实例,所有调用方都必须从单个实例请求信号量处理程序,否则它将无法工作。
    private static readonly SemaphoreSlim  ConcurrencySemaphore = 
                        new SemaphoreSlim(MaxConcurrencyPerSecond,MaxConcurrencyPerSecond);