下面的方法應該對第一個調用返回true,對於其他調用請返回false。我應該使用ManualResetEvent作爲鎖對象嗎?
它有什麼問題嗎?使用重置事件進行鎖定安全嗎?
private ManualResetEvent _resetEvent = new ManualResetEvent(false);
public bool AmIFirst()
{
lock (_resetEvent)
{
bool first = !_resetEvent.WaitOne(0);
if (first)
_resetEvent.Set();
return first;
}
}
編輯:我作了發言,回顧你的言論後的一些變化。由於以前的設計理念,我被困在ManualResetEvent
。我其實根本不需要它。
class ActionSynchronizer
{
private Timer _expirationTimer;
private object _locker = new object();
private bool _executionRequired = true;
private SomeDelegate _onExpired = delegate { };
public ActionSynchronizer(SomeDelegate onExpired)
{
_onExpired = onExpired;
expirationTimer = new Timer(OnExpired, null, 30000, Timeout.Infinite);
}
public bool IsExecutionRequired()
{
if (!_executionRequired)
return false;
lock (_locker)
{
if (_executionRequired)
{
_executionRequired = false;
return true;
}
return false;
}
}
private void OnExpired(object state)
{
if (_executionRequired)
{
lock (_locker)
{
if (_executionRequired)
{
_executionRequired = false;
// http://stackoverflow.com/questions/1712741/why-does-asynchronous-delegate-method-require-calling-endinvoke/1712747#1712747
_onExpired.BeginInvoke(_originalAction, EndInvoke, null);
}
}
}
}
}
// ...
{
if (_action.Sync.IsExecutionRequired())
_action.Invoke();
}
爲此+1 - 我喜歡 - 我是建議Interlocked,但不知道CompareExchange - 謝謝! – Stuart 2011-03-21 09:33:55
Thanks @Marc。如果您發現時間,請查看我的編輯。你認爲'聯鎖'仍然是一個合適的解決方案嗎? – HuBeZa 2011-03-21 10:14:50
@HuBeZa只要你在OnExpired中使用'Interlocked.CompareExchange(ref whatever,0,1)== 1',你應該沒問題。這表示「如果它是1,將其更改回0,並完成工作」,但是線程安全等 – 2011-03-21 10:44:57