【问题标题】:What happens to a SemaphoreSlim when you dereference it?取消引用 SemaphoreSlim 时会发生什么?
【发布时间】:2020-11-04 17:05:31
【问题描述】:

我在向 .NET Core Web 服务发送大量请求时遇到问题。我正在使用 SemaphoreSlim 来限制同时请求的数量。当我收到 10061 错误(Web 服务拒绝连接)时,我想回拨同时请求的数量。我目前的想法是取消引用 SemaphoreSlim 并创建另一个:

    await this.semaphoreSlim.WaitAsync().ConfigureAwait(false);
    counter++;

    Uri uri = new Uri($"{api}/{keyProperty}", UriKind.Relative);
    string rowVersion = string.Empty;
    try
    {
        HttpResponseMessage getResponse = await this.httpClient.GetAsync(uri).ConfigureAwait(false);
        if (getResponse.IsSuccessStatusCode)
        {
            using (HttpContent httpContent = getResponse.Content)
            {
                JObject currentObject = JObject.Parse(await httpContent.ReadAsStringAsync().ConfigureAwait(false));
                rowVersion = currentObject.Value<string>("rowVersion");
            }
        }
    }
    catch (HttpRequestException httpRequestException)
    {
        SocketException socketException = httpRequestException.InnerException as SocketException;
        if (socketException != null && socketException.ErrorCode == PutHandler.ConnectionRefused)
        {
            this.semaphoreSlim = new SemaphoreSlim(counter * 90 / 100, counter * 90 / 100);
        }
    }
}
finally
{
    this.semaphoreSlim.Release();
}

如果我这样做,在我刚刚取消引用的信号量上等待的其他任务会发生什么?我的猜测是,在对象被垃圾收集和处置之前,什么都不会发生。

【问题讨论】:

    标签: .net-core httpclient semaphore


    【解决方案1】:

    只要有对它的引用,SemaphoreSlim(就像 .NET 中的任何其他对象一样)就会存在。

    但是,您的代码中有一个错误:正在释放的 SemaphoreSlimthis.semaphoreSlim,如果 this.semaphoreSlim 在被获取和被释放之间发生变化,那么代码将释放与被收购。为避免此问题,请将this.semaphoreSlim 复制到方法开头的局部变量中,然后获取并释放该局部变量。

    更广泛地说,尝试的解决方案存在困难。如果您启动 1000 个任务,它们将全部引用旧信号量并忽略更新的this.sempahoreSlim。所以你需要一个单独的解决方案。例如,您可以定义一个一次性“令牌”,它是调用 API 的权限。然后有这些令牌的异步集合(例如,一个通道)。这使您可以完全控制一次释放多少令牌。

    【讨论】:

      猜你喜欢
      • 2016-06-14
      • 2017-03-08
      • 1970-01-01
      • 2015-02-24
      • 2013-02-26
      • 1970-01-01
      • 2011-03-25
      • 2013-04-29
      • 1970-01-01
      相关资源
      最近更新 更多