我想换一个Mutex
与IDisposable
类是这样的:结束语与IDisposable的互斥和测试,但测试永远不会结束
public class NamedMutex : IDisposable
{
private static readonly object _syncLock = new object();
private readonly Mutex _namedMutex;
private readonly bool _createdNew;
public NamedMutex(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
//lock (_syncLock)
{
_namedMutex = new Mutex(initiallyOwned: false, name: name, createdNew: out _createdNew);
}
_namedMutex.WaitOne();
}
public void Dispose()
{
//lock (_syncLock)
{
//if (_createdNew)
_namedMutex.ReleaseMutex();
_namedMutex.Dispose();
}
}
}
,你可以从注释掉的代码中,我看到尝试几乎所有我能想到的工作,但是要么是我的测试错误,要么是上面的实现不正确,因为测试要么永远不会结束(可能是一个死锁,我无法识别或崩溃,非同步异常)。
这是我的测试,我适合LINQPad:
void Main()
{
var sw = Stopwatch.StartNew();
var task1 = Task.Run(async() =>
{
using (new NamedMutex("foo"))
{
Console.WriteLine(3);
await Task.Delay(TimeSpan.FromSeconds(3));
}
});
var task2 = Task.Run(async() =>
{
using (new NamedMutex("foo"))
{
Console.WriteLine(2);
await Task.Delay(TimeSpan.FromSeconds(2));
}
});
Task.WaitAll(task1, task2);
//Assert.IsTrue(sw.Elapsed.TotalSeconds >= 5);
sw.Elapsed.Dump(); // LINQPad
}
你可以把一个断点'''NamedMutex'''的构造,并告诉我们,如果它曾经获得过'''_namedMutex.WaitOne();'''行? –
@MattThomas是的。如果我在它下面添加'Console.WriteLine(“WaitOne”);'它只打印一次'WaitOne',然后立即'3'并且它永远挂起。 – t3chb0t
我刚刚在visual studio中测试过它,它在第一次正常工作,但所有后续尝试都失败。然后,如果您更改互斥锁的名称,它将再次运行一次,然后再次失败。程序结束后,似乎互斥体没有正确处理。 –