Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用COM在C#web服务中侦听物理设备事件_C#_Multithreading_Web Services_Events_Com - Fatal编程技术网

如何使用COM在C#web服务中侦听物理设备事件

如何使用COM在C#web服务中侦听物理设备事件,c#,multithreading,web-services,events,com,C#,Multithreading,Web Services,Events,Com,我有一个web服务,它需要等待物理设备响应来进行一些处理并将结果返回给调用者。控制物理设备的DLL使用COM 代码如下: [WebMethod] public DeviceResponse SendDeviceRequest(int deviceId) { DeviceObject device = new DeviceObject(); AutoResetEvent resetEvent= new AutoResetEvent(false);

我有一个web服务,它需要等待物理设备响应来进行一些处理并将结果返回给调用者。控制物理设备的DLL使用COM

代码如下:

[WebMethod]
public DeviceResponse SendDeviceRequest(int deviceId)
    {
        DeviceObject device = new DeviceObject();

        AutoResetEvent resetEvent= new AutoResetEvent(false);
        EventHandler handler = new EventHandler (Device,resetEvent);

        handler.subscribeEvent(); 

        device.requestResponse(deviceId);

        resetEvent.WaitOne(); //wait until device has fired the response event

        //Do processing with device response
    }
以下是EventHandler类:

public class EventHandler
{
    DeviceObject device;
    AutoResetEvent resetEvent;

    public EventHandler (DeviceObject deviceObject,AutoResetEvent are)
    {
        device= deviceObject;
        resetEvent = are;
    }

    public void subscribeEvent()
    {
        device.OnDeviceResponse += new OnDeviceResponseEventHandler(OnResponse);
    }

    public void OnResponse(CustomParams params) 
    {
        //handle device response
        resetEvent.Set();
    }
}
我遇到的问题是,
OnResponse
方法从未执行,并且该方法一直在等待
resetEvent.Set()
。但是,如果我使用WindowsForms实现EventHandler,即使不使用
AutoResetEvents
对象,事件也会得到正确处理。我强烈怀疑这是由于COM线程和主线程之间的通信中断造成的

接下来的问题是:如何让COM线程和主线程通信,以便侦听COM DLL中触发的设备事件?我是否必须自己实现线程单元处理过程(以便它像在Windows窗体应用程序中一样工作),或者.NET已经提供了一种机制来实现这一点?

尝试替换:

    handler.subscribeEvent(); 

    device.requestResponse(deviceId);

    resetEvent.WaitOne();//wait until device has fired the response event
    //Do processing with device response
与:


我想到的第一个也是最明显的问题是:你确定设备的
requestResponse
方法实际上是异步的吗?
device.requestResponse(deviceId)
做什么,你确定它触发了
OnDeviceResponse
?@Alden device.requestResponse(deviceId)向具有给定id的设备发送执行操作的请求。之后,控制权交给设备。设备在处理完设备发出的请求后触发OnDeviceResponse事件。requestResponse(deviceId)方法。@DavidH requestResponse方法是同步执行的,但我不确定如何处理来自设备的异步事件,也不确定为什么相同的实现在windows窗体应用程序中工作。任何指导都将不胜感激。更改后的结果是一样的。不知何故,当设备触发事件时,EventHandler没有进入OnResponse方法。从逻辑上讲,只能假设设备从未引发事件。太奇怪了。因为我知道如果我使用Windows窗体应用程序实现它,这是可行的,我的代码的唯一区别是我没有使用STAThread属性,我想这可能是原因。我以前没有使用它的原因是因为我被告知该设备的DLL不使用COM,但我相信他们使用COM。我明天会确认这一点,并让你知道发生了什么。我测试了提到的更改,但它不起作用。进一步阅读后,问题似乎来自与控制物理设备的COM DLL的通信。我将编辑OP以反映这一点。我终于能够与触发事件的库的提供商交谈,结果发现他们没有向我使用的COM库添加对多线程单元的支持。如果使用单个线程,订阅@DavidHaney建议的事件确实有效。
    handler.subscribeEvent(); 

    var thread = new Thread(() =>
    {
        device.requestResponse(deviceId);
    });
    thread.Start();

    resetEvent.WaitOne();//wait until device has fired the response event

    //Do processing with device response