Приведенный ниже метод должен возвращать true для первого вызова и false для любого другого вызова.
Есть ли с этим проблемы? Безопасно ли использовать событие сброса для блокировки?
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;
// /951548/pochemu-asinhronnyi-metod-delegata-trebuet-vyzova-endinvoke#951551
_onExpired.BeginInvoke(_originalAction, EndInvoke, null);
}
}
}
}
}
// ...
{
if (_action.Sync.IsExecutionRequired())
_action.Invoke();
}