问题
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()
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();
}
回答1:
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();
}
}
来源:https://stackoverflow.com/questions/51243382/c-sharp-how-to-achieve-monitor-enter-exit-with-task-based-async