Попытка:
public class KeyLock : IDisposable
{
private string key;
private static ISet<string> lockedKeys = new HashSet<string>();
private static object locker1 = new object();
private static object locker2 = new object();
public KeyLock(string key)
{
lock(locker2)
{
// wait for key to be freed up
while(lockedKeys.Contains(key));
this.lockedKeys.Add(this.key = key);
}
}
public void Dispose()
{
lock(locker)
{
lockedKeys.Remove(this.key);
}
}
}
, которая будет использоваться как
using(new KeyLock(str))
{
// section that is critical based on str
}
Я проверяю, дважды запуская метод за один и тот же промежуток времени
private async Task DoStuffAsync(string str)
{
using(new KeyLock(str))
{
await Task.Delay(1000);
}
}
// ...
await Task.WhenAll(DoStuffAsync("foo"), DoStuffAsync("foo"))
но, как ни странноДостаточно, когда я отлаживаю, я вижу, что во второй раз он проходит прямо через lock
и на самом деле как-то lockedKeys.Contains(key)
оценивается до false
, даже когда я вижу в своих окнах отладчика, что ключ есть.
Где недостаток и как его исправить?