Dev*_*est 2 .net c# multithreading semaphore
我需要一段代码,根据参数键只允许同时由 1 个线程执行:
private static readonly ConcurrentDictionary<string, SemaphoreSlim> Semaphores = new();
private async Task<TModel> GetValueWithBlockAsync<TModel>(string valueKey, Func<Task<TModel>> valueAction)
{
var semaphore = Semaphores.GetOrAdd(valueKey, s => new SemaphoreSlim(1, 1));
try
{
await semaphore.WaitAsync();
return await valueAction();
}
finally
{
semaphore.Release(); // Exception here - System.ObjectDisposedException
if (semaphore.CurrentCount > 0 && Semaphores.TryRemove(valueKey, out semaphore))
{
semaphore?.Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我时不时地收到错误:
The semaphore has been disposed. : System.ObjectDisposedException: The semaphore has been disposed.
at System.Threading.SemaphoreSlim.CheckDispose()
at System.Threading.SemaphoreSlim.Release(Int32 releaseCount)
at Project.GetValueWithBlockAsync[TModel](String valueKey, Func`1 valueAction)
Run Code Online (Sandbox Code Playgroud)
我在这里能想象到的所有情况都是线程安全的。请帮忙,我错过了什么案例?
这里有一个线程竞赛,其中另一个任务正在尝试获取相同的信号量,并在您Release(即另一个线程正在等待semaphore.WaitAsync(). 检查CurrentCount是一种竞争条件,根据时间的不同,它可能会发生任何一种情况。检查TryRemove是无关紧要的,因为竞争线程已经获取了信号量 - 毕竟它正在等待WaitAsync().