using System.Collections.Concurrent;
using System.Threading;
namespace Examino.Infrastructure
{
public class MutexProviderService : IMutexProviderService
{
private readonly ConcurrentDictionary<string, object> mutexCollection;
public MutexProviderService()
{
mutexCollection = new ConcurrentDictionary<string, object>();
}
public void Enter(string key)
{
Monitor.Enter(GetMutex(key));
}
public void Exit(string key)
{
Monitor.Exit(GetMutex(key));
}
public object GetMutex(string key)
{
return mutexCollection.GetOrAdd(key, (s) => new object());
}
}
public interface IMutexProviderService
{
object GetMutex(string key);
void Enter(string key);
void Exit(string key);
}
}
我通过多个TPL任务测试这个类,并看到
lock (mutexProviderService.GetMutex(lockName)) {}
可靠地锁定关键部分和
mutexProviderService.Enter(lockName);
try { }
finally
{
mutexProviderService.Exit(lockName);
}
不可靠。手动调用使用相同实例参数调用definitelly的Enter / Exit有什么问题? 附:来自MSDN的命名互斥代码比这个类要大得多,也更复杂。
答案 0 :(得分:0)
这实际上不是您问题的答案,但从c#4.0开始,lock
会生成下一个代码(阅读this文章):
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
{ body }
}
finally
{
if (lockWasTaken) Monitor.Exit(temp);
}