c# - 使用进程间同步对象同步 2 个进程 - Mutex 或 AutoResetEvent

标签 c# .net synchronization pinvoke mutex

考虑以下场景:我正在运行我的应用程序,该应用程序在执行期间必须运行另一个进程,并且只有在第二个进程完成内部特定初始化之后,我的第一个进程才能继续。例如:

...
// Process1 code does various initializations here
Process.Start("Process2.exe");
// Wait until Process2 finishes its initialization and only then continue (Process2 doesn't exit)
...

我看到几个选项:

  1. Mutex - 在考虑进程间通信时会自动想到 Mutex,但是,我看不出有什么方法可以让 Process1 等待他自己生成的互斥锁。我可以让 Process2 创建一个互斥量并在 Process1 上等待直到创建互斥量(使用轮询和 Mutex.OpenExisting 函数)
  2. AutoResetEvent - 这些对于任务来说是完美的,但是,在 .NET 下,这些似乎不能用于进程间通信。
  3. CreateEvent - 我可以使用 P/Invoke 和 Win32 CreateEvent 函数。理论上,它可以为我提供我需要的一切。但是,如果可能的话,我宁愿不使用 native 函数。
  4. 使用外部文件 - 最简单的方法就是使用一些操作系统外部对象(文件、注册表等)。然而,这似乎很老套。

我很高兴听到您对这个案例的意见。

谢谢!

最佳答案

我正要编辑 this answer , 但它似乎不正确。所以我会发布我自己的...

根据Threads for C#页面,里面有很多同步教程,AutoResetEvent不能用于进程间同步。


然而,一个名为 EventWaitHandle可用于进程间同步。 在上面的页面中,访问Creating a Cross-Process EventWaitHandle部分。

您设置它的方式很简单:

进程 1

EventWaitHandle handle = new EventWaitHandle(
    false,                                /* Create handle in unsignaled state */
    EventResetMode.ManualReset,           /* Ignored.  This instance doesn't reset. */
    InterprocessProtocol.EventHandleName  /* String defined in a shared assembly. */
);

ProcessStartInfo startInfo = new ProcessStartInfo("Process2.exe");
using (Process proc = Process.Start(startInfo))
{
    //Wait for process 2 to initialize.
    handle.WaitOne();

    //TODO
}

进程 2

//Do some lengthy initialization work...

EventWaitHandle handle = new EventWaitHandle(
    false,                           /* Parameter ignored since handle already exists.*/
    EventResetMode.ManualReset,          /* Explained below. */
    InterprocessProtocol.EventHandleName /* String defined in a shared assembly. */
);
handle.Set(); //Release the thread waiting on the handle.

现在,关于 EventResetMode . 选择 EventResetMode.AutoReset 还是 EventResetMode.ManualReset 取决于您的应用。

在我的例子中,我需要手动重置,因为我有许多进程连接到同一个进程。因此,一旦这个相同的进程完成初始化,所有其他进程都应该能够工作。因此, handle 应保持信号状态(无复位)。

对于您来说,如果您每次进程 1 启动进程 2 时都必须执行初始化,那么自动重置可能会有所帮助。


旁注: InterprocessProtocol.EventHandleName 只是一个包装在 DLL 中的常量,process 1process 2 引用。您不需要这样做,但它可以防止您输入错误的名称并导致死锁。

关于c# - 使用进程间同步对象同步 2 个进程 - Mutex 或 AutoResetEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4123923/

相关文章:

c# - 如何使[示例]扩展方法更加通用/实用/高效?

java - Cloudant j2se 原型(prototype)抛出 HTTPRequest 异常

c# - 将 JavaScript 与 C# 结合使用用于非基于浏览器的操作

c# - 表单在获取所有数据之前打开。如何让 UI 线程等待处理线程的第一个周期完成?

c# - 使用 XadES-BES 算法通过 XMLDSIG 进行 XML 验证

java - 当一个线程获取锁时,其他线程是否可以调用其他方法?

javascript - 同步迭代javascript对象

c# - 如何在 ASP.NET MVC 中通过 Ajax 提交表单?

c# - 比较 7 个单词,看看其中 5 个是否相等。如何?

c# - 非字符串的 .net 本地化