在托管进程中使用 EventWaitHandle 和在非托管进程中使用 WaitForSingleObject 进行跨进程同步

Posted

技术标签:

【中文标题】在托管进程中使用 EventWaitHandle 和在非托管进程中使用 WaitForSingleObject 进行跨进程同步【英文标题】:Cross process synchronization using EventWaitHandle in managed process and WaitForSingleObject in unmanaged process 【发布时间】:2012-10-16 23:35:39 【问题描述】:

我有两个进程,一个使用 C# 创建,另一个使用原生 C++ 创建。

我想同步这两个进程,这样非托管进程就会被阻塞,直到托管进程启动并运行。

在托管进程中,我有以下代码:

// signal the unmanaged process that I am up and running
EventWaitHandle eventWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, "MyEventName");
eventWaitHandle.Set();

在非托管进程中我有相应的代码等待事件

HANDLE hWaitEvent = CreateEventW(NULL, TRUE, FALSE, "MyEventName"); 
if (hWaitEvent)

    // wait for managed process to signal that it is up and running
    WaitForSingleObject(hWaitEvent, 5000);

据我所知,事件是在第一个过程中设置的。其他进程中的 WaitForSingleObject 无法检测到这一点,并始终等到超时。

有什么我错过的吗?谢谢。

【问题讨论】:

【参考方案1】:

Hans Passant 的建议是对的,我在 C++ 中打开事件时需要 SYNCHRONIZE 访问权限。

这是有效的代码:

在托管进程中:

    EventWaitHandle _initializedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\Initialized");

在本机进程中:

    const WCHAR* initializedEventName = L"Global\\Initialized";
    int attempt = 0;
    HANDLE eventHandle = NULL;
    while ((eventHandle = OpenEventW(SYNCHRONIZE, FALSE, initializedEventName)) == NULL && attempt < 5)
    
       Sleep(1000);
       ++attempt;
    

    if (eventHandle != NULL)
    
       WaitForSingleObject(eventHandle, 5000);
       CloseHandle(eventHandle);
    

【讨论】:

【参考方案2】:

是的,这不起作用,您正在两端创建一个事件。其中一个必须创建它,另一个必须打开它。 C++ 代码中的 OpenEvent() 或 C# 代码中的 EventWaitHandle.OpenExisting()。无论代码首先开始,都必须创建事件。

【讨论】:

谢谢。现在我使用 HANDLE hWaitEvent = OpenEventW(NULL, TRUE, eventName);打开活动。但是 hWaitEvent 为空。我需要指定第一个参数而不是 NULL 吗? 使用 GetLastError()。您的论点非常随机,您需要请求 SYNCHRONIZE 访问。如果两个进程在不同的会话中(如服务),那么您需要在事件名称前加上“Global\”。

以上是关于在托管进程中使用 EventWaitHandle 和在非托管进程中使用 WaitForSingleObject 进行跨进程同步的主要内容,如果未能解决你的问题,请参考以下文章

EventWaitHandle 没有在进程终止时关闭

使用 EventWaitHandle 类

EventWaitHandle

我需要 Dispose() 或 Close() EventWaitHandle 吗?

.NET EventWaitHandle 慢

EventWaitHandle 第一课