我正在尝试创建一个接受委托的通用方法。该方法的唯一目的是确保传递给它的任何唯一代码块,一次只能由一个线程访问。我指出这个单词是唯一的,因为唯一的代码块可以并行运行,重复的代码块必须同步运行。是否有一个干净的模式来实现这一目标?
答案 0 :(得分:2)
您可以这样做:
namespace RunSafe
{
// Declare a delegate type
public delegate void RunSafeDelegate();
public class SafeRunner
{
private object _lock = new Object();
public void Runner( RunSafeDelegate runsafe )
{
lock( this._lock )
{
runsafe();
}
}
}
}
答案 1 :(得分:0)
最终,Dex Star的代码示例引领我走上了我想要的道路。
如果有任何疑虑,请告诉我。我相信这是一个可靠的解决方案。注意我故意使用命名的互斥锁,因为访问资源可能涉及多个进程。
// test code
RunSafeDelegate rsd1 = () => { /* some code i need synchronous */ };
RunSafeDelegate rsd2 = () => { /* other code i need synchronous */ };
var util = new UtilityClass();
util.RunSafe(rsd1, "myMutexName1");
util.RunSafe(rsd2, "myMutexName2");
// implementation
public class UtilityClass
{
public delegate void RunSafeDelegate();
public void RunSafe(RunSafeDelegate runSafe, string mutexName)
{
const int WAIT_ONE_TIMEOUT = 30000;
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var mar = new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow);
var ms = new MutexSecurity();
ms.AddAccessRule(mar);
bool mutexCreated;
using(var mutex = new Mutex(false, mutexName, out mutexCreated, ms))
{
var signalReceived = false;
try
{
try
{
signalReceived = mutex.WaitOne(WAIT_ONE_TIMEOUT, false);
if(!signalReceived)
{
throw new TimeoutException("Exclusive access timeout for mutex: " + mutexName);
}
}
catch(AbandonedMutexException)
{
signalReceived = true;
}
runSafe();
}
finally
{
if(signalReceived)
{
mutex.ReleaseMutex();
}
}
}
}
}