c# - 将同步包装器放在异步方法上

标签 c# events asynchronous synchronous

我正在使用包含异步方法的 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/

相关文章:

c# - Restful WCF 服务身份验证

c# - 是否可以访问图形路径中的点?

asp.net - 来自 asp.net ASHX 页面的 FullCalendar 事件未显示

c# - 在不需要时使用异步等待的性能影响

javascript - meteor 延迟 - 对 react 性的影响

c++ - V8 javascript如何进行异步调用

c# - 我们如何在 C# 中使用 TcpListener 发送数据?

c# - 使用全局变量的 WPF 应用程序

c# - 调用跨线程事件的最简洁方法

java - 如何监听 GWT 中 Editor<?> 上的小部件触发的 ValueChangedEvents?