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

Vit*_*lyB 15 .net c# pinvoke synchronization 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)
...
Run Code Online (Sandbox Code Playgroud)

我看到几个选项:

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

我很高兴听到你对这个案子的意见.

谢谢!

Nic*_*ler 16

我只是想编辑这个答案,但这似乎不正确.所以我会张贴自己的......

根据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
}
Run Code Online (Sandbox Code Playgroud)

过程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.
Run Code Online (Sandbox Code Playgroud)

现在,关于EventResetMode.无论您选择EventResetMode.AutoReset还是EventResetMode.ManualReset取决于您的申请.

就我而言,我需要手动重置,因为我有许多进程连接到同一进程.因此,一旦初始化完成相同的过程,所有其他过程应该能够工作.因此,手柄应保持信号状态(不复位).

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


旁注:InterprocessProtocol.EventHandleName只是一个包含在DLL中的常量,它包括进程1进程2引用.您不需要这样做,但它可以保护您不会错误输入名称并导致死锁.


use*_*631 11

我会考虑**AutoResetEvent**.它们可以用于进程间通信,它们相对快速.请参阅以下链接:c#的主题

阅读创建跨进程EventWaitHandle部分...

  • AutoResetEvent只能是本地的.但你是对的 - EventWaitHandle正是我想要的.谢谢! (4认同)
  • 为什么不能使用 AutoResetEvent 和 ManualResetEvent 进行进程间通信?它们都源自 EventWaitHandle (2认同)