我正在尝试调整现有程序(内部编写)以使用与原来不同的库。我已经抽象了大部分特定于库的代码(似乎是更容易的部分)。
问题是,旧库将使用阻塞方法执行调用,并且我们的内部程序期望调用阻塞方法,但新库使用异步方法。
我想知道等待异步操作完成的最佳做法是什么。我的第一个想法是有一个名为completed的布尔标志,并在while循环中旋转直到完成== true。
我应该注意,这是为了快速证明我正在为我的利益相关者整理的概念,如果利益相关者签署了该项目,我将重写我们计划中令人讨厌的部分。但就目前而言,我需要等待阻塞调用异步方法的函数,直到异步调用完成为止
答案 0 :(得分:2)
将倒计时锁存器传递给异步方法,然后等待锁存器。当异步方法完成时,它将通过倒计时锁存器通知您,并且可以继续执行。原则上也可以使用监视器,但是在不熟练的情况下,异步方法在你可以调用wait之前完成是不安全的,因此你错过了通知。
哦,在.NET世界中,倒计时锁存器称为CountdownEvent:CountdownEvent Class
答案 1 :(得分:2)
我认为您不想使用旗帜,而是想要使用mutex之类的东西。
为了做到这一点,该库需要有一个事件,以便在异步调用完成后通知您。它看起来像这样:
自从我使用这些东西已经有一段时间了,但我很确定它应该如何运作。
编辑:哎呀,我想我想的是semaphore,而不是互斥:
private static Semaphore mySemaphore = new Semaphore(0, 1);
static void Main(string[] args)
{
Console.WriteLine("Waiting on async call");
(new Thread(ASyncCallCompleted)).Start();
mySemaphore.WaitOne();
Console.WriteLine("Waiting Completed");
}
private static void ASyncCallCompleted()
{
Thread.Sleep(5000);
mySemaphore.Release();
}
编辑#2 :Per Thorarin的建议;听起来这个类被设计用于处理.Net中的这种情况:
private static AutoResetEvent mySync = new AutoResetEvent(false);
static void Main(string[] args)
{
Console.WriteLine("Waiting on async call");
(new Thread(ASyncCallCompleted)).Start();
mySync.WaitOne();
Console.WriteLine("Waiting Completed");
Console.Read();
}
private static void ASyncCallCompleted()
{
Thread.Sleep(5000);
mySync.Set();
}
答案 2 :(得分:1)
这最多只能同时调用BlockingCall
。否则,您将需要单独的AutoResetEvent
实例来确定哪个呼叫已完成。无论如何:
delegate void Callback();
class BlockAsync
{
AutoResetEvent _waitHandle = new AutoResetEvent(false);
public void BlockingCall()
{
AsyncCall(AsyncCallCompleted);
_waitHandle.WaitOne();
}
void AsyncCall(Callback callback)
{
// Example is not actually asynchronous, to demonstrate the solution
// is free of race conditions.
callback();
}
void AsyncCallCompleted()
{
_waitHandle.Set();
}
}