C#如何实现Monitor.Enter / Exit与基于任务的异步

时间:2018-07-09 10:29:01

标签: c# multithreading asynchronous locking

这是我的代码。如果不是基于任务的异步,则无需执行此操作,但是使用Monitor.Enter / Exit会导致此问题Object synchronization method was called from an unsynchronized block of code. Exception on Mutex.Release()

人们提到使用AutoResetEvent和SemaphoreSlim,但是我不确定哪种模式适合。

private bool fakelock;

internal async Task<byte[][]> ExchangeCore(byte[][] apdus)
{
    if (apdus == null || apdus.Length == 0)
        return null;
    List<byte[]> resultList = new List<byte[]>();
    var lastAPDU = apdus.Last();

    while (fakelock)
    {
        await Task.Delay(100);
    }

    fakelock = true;

    foreach (var apdu in apdus)
    {
        await WriteAsync(apdu);
        var result = await ReadAsync();
        resultList.Add(result);
    }

    fakelock = false;

    return resultList.ToArray();
}

1 个答案:

答案 0 :(得分:1)

您也许可以使用支持异步的SemaphoreSlim。

private static SemaphoreSlim Semaphore = new SemaphoreSlim(1, 1);

internal async Task<byte[][]> ExchangeCore(byte[][] apdus)
{
    if (apdus == null || apdus.Length == 0)
        return null;

    await Semaphore.WaitAsync();

    try
    {
        List<byte[]> resultList = new List<byte[]>();
        foreach (var apdu in apdus)
        {
            await WriteAsync(apdu);
            var result = await ReadAsync();
            resultList.Add(result);
        }
        return resultList.ToArray();
    }
    finally
    {
        Semaphore.Release();
    }
}