【问题标题】:How to release all threads using SemaphoreSlim, when one of them did some action?当其中一个线程执行某些操作时,如何使用 SemaphoreSlim 释放所有线程?
【发布时间】:2021-11-16 23:59:28
【问题描述】:

我有一些代码在其中使用SemaphoreSlim

if (!string.IsNullOrEmpty(UserSettings.Token) && !isWithoutRefresh)
{

    if (UserSettings.Expires < ConvertToTimestamp(DateTime.UtcNow.AddMinutes(2)))
    {

        await _locker.LockAsync(async () =>
        {

            if (UserSettings.Expires < ConvertToTimestamp(DateTime.UtcNow.AddMinutes(2)))
            {
                if (Role.Guest.Equals(UserSettings.Role)
                    && !string.IsNullOrEmpty(UserSettings.Email))
                {
                    //TODO: initialize guest session
                }
                else
                {
                    await RefreshToken(httpClient);
                    await AlertService.ShowAsync("Odswiezony");
                }
            }
        });
    }
}

这是我_locker的代码:

private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

public async Task LockAsync(Func<Task> worker)
{
    await _semaphore.WaitAsync();
    try
    {
        await worker();
    }
    finally
    {
        _semaphore.Release();
    }
}

我的问题是,在储物柜内的一个线程执行某些操作后,我能做些什么来异步释放所有线程?因为在这种情况下,每个线程都会同步进行。我想要的解决方案是在我需要刷新令牌时具有逻辑,并且多个线程可以使此操作仅允许其中的第一个执行此操作,并使其余的线程异步。

【问题讨论】:

  • 我不确定我是否理解正确,但SemaphoreSlim 的重点是异步等待资源可以再次使用——你已经在这样做了。如果第一个线程开始刷新你的令牌,其他线程将等待它完成。
  • 是的没错,但是其他线程会一个接一个地执行,但我想并行执行
  • 在这种情况下,锁定的意义何在?如果您删除信号量处理,它将按预期工作,不是吗?
  • 不,因为,如果我删除 semaphoreSlim,不止一个线程会刷新令牌,而不仅仅是一个
  • 所以你希望 first 线程刷新,而 others 什么也不做,只是等到第一个线程完成......然后什么都不做对吧?

标签: c# .net multithreading asynchronous semaphore


【解决方案1】:

SemaphoreSlim 用于互斥。它非常适合限制并发性——在这种情况下,一次限制为一个。但你要做的不是互斥。

在这种情况下,您真正想要的是一个恰好包含单个项目的异步缓存。 AFAIK 目前不存在适当的异步缓存,但我有一个经过部分测试、半验证的here

或者您可以自己构建。我建议从异步手动重置事件开始(基于Stephen Toub's code 或使用我的AsyncEx library);那么您需要添加决定根据您的到期令牌“重置”它的逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多