C#工作线程调用com服务器和WaitForSingleObject意外超时。 [英] C# worker thread calls com server and WaitForSingleObject times out unexpectedly.

查看:75
本文介绍了C#工作线程调用com服务器和WaitForSingleObject意外超时。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近阅读了对此帖子的质量响应"C#调用COM接口后C ++ COM服务器中的线程问题"由Lim Bio Liong提供,这让我希望有人可以解释我们所看到的失败。 我们有一个传统的MFC dll
,它有一个启动数据泵的COM方法。该方法称为Start,函数中的第一行代码是  DWORD iWait = WaitForSingleObject(eventStartingPump,10000);在加载dll时构造包含Start方法的类。
事件对象 eventStartingPump,是在类的构造函数中发出信号创建的。从COM接口类调用Start方法。接口方法由在此等待的C#工作线程调用  Monitor.Wait
(m_locker);并通过调用  Monitor.Pulse(this.m_locker)来释放OnRender中的C#主线程; 在C ++端,事件句柄被声明为static并初始化为  HANDLE Foo :: eventStartingPump
= NULL;在类构造函数中,事件的创建方式如下:

I recently read the quality response to this posting "Thread Issue in C++ COM Server after C# call COM Interface" by Lim Bio Liong and that gave me hope that someone could explain a failure we are seeing.  We have a legacy MFC dll with a COM method that starts a data pump. The method is called Start and the first line of code in the function is DWORD iWait = WaitForSingleObject( eventStartingPump, 10000 ); The class containing the Start method is constructed when the dll is loaded. The event object, eventStartingPump, is created as signaled in the constructor of the class. The Start method is called from a COM interface class. The interface method is called by a C# worker thread that waits here Monitor.Wait (m_locker); and is released by the C# main thread in OnRender by calling Monitor.Pulse (this.m_locker);  On the C++ side the event handle is declared as static and initialize as HANDLE Foo::eventStartingPump = NULL; In the class constructor the event is created like so:

   eventStartingPump = :: CreateEvent(NULL,//没有安全属性

      FALSE,//手动重置

       TRUE,//最初发出信号为
      NULL); //匿名

   eventStartingPump = ::CreateEvent(NULL, // no security attributes
      FALSE, // manual-reset
      TRUE, // initially signaled
      NULL);// anonymous




选择 WaitForSingleObject 是为了防止在函数中运行多个线程并强制执行长时间的延迟返回前的第二个线程。问题是,这大约95%的时间按预期工作,但大约
5%的时间  WaitForSingleObject超时。我们已经对代码进行了检测,以确保在构造函数和start函数中执行都是预期的。如果 WaitForSingleObject在程序启动后第一次执行时没有
超时,它将始终按预期执行。失败的是进入函数的第一个线程在大约5%的时间内超时。但是,一旦失败,它将永远失败,除非我们将代码更改为
call 
SetEvent( eventStartingPump );超时后。换句话说,事件对象的行为就好像它不是作为信号创建的那样。当MFC GUI到MFC服务器时,此接口有100%的时间工作。 

The WaitForSingleObject was chosen both to prevent more than one thread running in the function and to enforce a long delay of a second thread before returning. The problem is that this works about 95% of the time as expected but about 5% of the time the WaitForSingleObject times out. We have instrumented the code to ensure the execution is as expected both in the constructor and within the start function. If the WaitForSingleObject doesn't time out on the first execution after the program starts it will always execute as expected. The failure is that the first thread to enter the function times out about 5% of the time. However, once it fails it will always fail unless we change the code to call SetEvent(eventStartingPump); after the time out. In other words the event object is acting as though it was not created as signaled. This interface worked 100% of the time when it was MFC GUI to MFC server. 

推荐答案

< guess> IIRC可以通过
dllmain()
来做一些奇怪的事情。因此,您可以尝试在加载DLL后在方法中创建事件< / guess>

<guess> IIRC there can be some weirdness doing stuff from dllmain(). So you might try creating the event in a method after the DLL is loaded</guess>

如果您只有一个用于此DLL的C#客户端应用程序,我会将所有同步推送到C#代码。 你已经有了一个监视器等待循环。 即使这是一个进程外的COM服务器,您也可以使用名为
Mutex

If you have only the one C# client app for this DLL, I would push all the synchronization into the C# code.  You already have a Monitor wait loop there.  Even if this is an out-of-process COM server, you can do cross-process synchronization from C# with a named Mutex.

否则你可能会必须建立一个简化的repro来解决这个问题。 它将打开COM线程模型的一些可怕的旧细节。 :(

Otherwise you'll probably have to build a simplified repro to figure this out.  It will turn on some horrible old detail of the COM threading models. :(

David


这篇关于C#工作线程调用com服务器和WaitForSingleObject意外超时。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆