C#如何实现Monitor.Enter/Exit与基于任务的异步 [英] C# How To Achieve Monitor.Enter/Exit With Task Based Async

查看:100
本文介绍了C#如何实现Monitor.Enter/Exit与基于任务的异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的有效代码.如果不是基于任务的异步,则不必执行此操作,但是使用Monitor.Enter/Exit会导致此问题

This is my code that works. I wouldn't have to do this if it weren't task based async, but using Monitor.Enter/Exit results in this problem Object synchronization method was called from an unsynchronized block of code. Exception on Mutex.Release()

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

People have mentioned using AutoResetEvent, and SemaphoreSlim, but I'm not quite sure which pattern fits.

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();
}

推荐答案

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

You could maybe use a SemaphoreSlim which supports async.

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();
    }
}

这篇关于C#如何实现Monitor.Enter/Exit与基于任务的异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆