c# - 当其中一个线程执行某些操作时,如何使用 SemaphoreSlim 释放所有线程?
问题描述
我有一些我使用的代码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
是为了互斥。它非常适合限制并发性——在这种情况下,一次限制为一个。但你想做的不是互斥。
在这种情况下,您真正想要的是一个恰好包含单个项目的异步缓存。AFAIK 目前不存在适当的异步缓存,但我在这里有一个经过部分测试、半验证的缓存。
或者你可以建立你自己的。我建议从异步手动重置事件开始(基于Stephen Toub 的代码或使用我的AsyncEx 库);那么您需要添加决定根据您的到期令牌“重置”它的逻辑。
推荐阅读
- jenkins - 将角色从 Keycloak 客户端角色映射到 Jenkins
- javascript - 在访问对象数组时遇到问题
- javascript - 收到此错误 EIO:创建反应应用程序时出现 i/o 错误
- python - 烧瓶网络套接字未连接
- c - 将不变的代码放在单独的内存部分,以减少 OTA 更新大小
- javascript - TypeError:无法读取未定义的属性“s_path”(React Native)
- node.js - 使用 docker-compose up 启动交互式 node.js CLI 应用程序
- javascript - 如何取消 QDate 选择?
- wordpress - 通过单击变体图像 Woocommerce 更改产品变体
- reactjs - React 条件格式三元