我应该使用ManualResetEvent作为锁定对象吗?

HuB*_*eZa 4 .net c# multithreading manualresetevent

对于第一次调用,下面的方法应返回true,对于任何其他调用,返回false.

它有什么问题吗?使用重置事件进行锁定是否安全?

private ManualResetEvent _resetEvent = new ManualResetEvent(false);

public bool AmIFirst()
{
    lock (_resetEvent)
    {
        bool first = !_resetEvent.WaitOne(0);
        if (first)
            _resetEvent.Set();

        return first;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:我在评论你的评论后做了一些修改.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();
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 13

我会在这里走另一条路......

private int counter;
...
if(Interlocked.Increment(ref counter) == 1)
{
     // yes, I'm first
}
Run Code Online (Sandbox Code Playgroud)

线程安全,没有锁.或者,如果您担心包围Int32:

if(Interlocked.CompareExchange(ref counter, 1, 0) == 0)
{
     // yes, I'm first
}   
Run Code Online (Sandbox Code Playgroud)

  • 为此+1 - 我喜欢 - 我建议互联,但不知道CompareExchange - 谢谢! (2认同)