我正在使用包含异步方法的 API 与 PIN 设备集成。例如,其中一个称为 GetStatus,它会引发 DeviceStateChangedEvent,并将状态作为参数传递给它。
不过,我希望有一个不是异步的接口(interface),这样当我在我的接口(interface)上调用 GetStatus 时,它实际上会返回状态,而不是引发一个事件来将数据传递给我。
我想我可以做这样的事情:
public class MSRDevice
{
StatusInfo _status;
bool _stateChangedEventCompleted = false;
IPAD _ipad; // <-- the device
public MSRDevice()
{
//Initialize device, wire up events, etc.
}
public StatusInfo GetStatus()
{
_ipad.GetStatus() // <- raises StatusChangedEvent
while(!_stateChangedEventCompleted);
_stateChangedEventCompleted = false;
return _status;
}
void StateChangedEvent(object sender, DeviceStateChangeEventArgs e)
{
_status = e.StatusInfo;
}
}
这是解决这个问题的好方法还是有更好的解决方案?
最佳答案
你在你的例子中所做的叫做“busy-waiting ”(或“旋转”),这在大多数情况下是不推荐的,因为它会浪费大量的 CPU 能力。您最好使用信号机制,例如 WaitHandle
类,以便在感兴趣的事件(在您的情况下为 StatusChangedEvent
)发生时进行同步:
public class MSRDevice
{
StatusInfo _status;
IPAD _ipad; // <-- the device
private EventWaitHandle waitHandle = new AutoResetEvent(false);
public MSRDevice()
{
//Initialize device, wire up events, etc.
}
public StatusInfo GetStatus()
{
_ipad.GetStatus() // <- raises StatusChangedEvent asynchronously
waitHandle.WaitOne(); // <- waits for signal
return _status;
}
void StateChangedEvent(object sender, DeviceStateChangeEventArgs e)
{
_status = e.StatusInfo;
waitHandle.Set(); // <- sets signal
}
}
关于c# - 将同步包装器放在异步方法上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9368602/