Locking with nested async calls

前端 未结 4 1506
轮回少年
轮回少年 2021-02-13 11:50

I am working on a multi threaded WindowsPhone8 app that has critical sections within async methods.

Does anyone know of a way to properly use semaphores / mutexes in C

4条回答
  •  暖寄归人
    2021-02-13 12:27

    You can use the System.Threading.ReaderWriterLockSlim (doc), which has a support recursion flag:

    ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
    
    async Task Bar()
    {
        try
        {
            _lock.EnterReadLock();
            await BarInternal();
        }
        finally
        {
            if (_lock.IsReadLockHeld)
                _lock.ExitReadLock();
        }
    }
    
    async Task BarInternal()
    {
        try
        {
            _lock.EnterReadLock();
            await Task.Delay(1000);
        }
        finally
        {
            if (_lock.IsReadLockHeld)
                _lock.ExitReadLock();
        }
    }
    

    Still you should be very careful with recursion because it is very difficult to control which thread took a lock and when.

    The code in the question will be result in a deadlock because it tries to acquire the lock twice, something like:

    await _lock.WaitAsync();
    await _lock.WaitAsync(); --> Will result in exception.
    

    While flagging the ReaderWriterLockSlim in SupportsRecursion will not throw an exception for this weird code:

     _lock.EnterReadLock();
     _lock.EnterReadLock();
    

提交回复
热议问题