如何使用COM在C#web服务中侦听物理设备事件
我有一个web服务,它需要等待物理设备响应来进行一些处理并将结果返回给调用者。控制物理设备的DLL使用COM 代码如下:如何使用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);
[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