【问题标题】:Preventing a second instance from running except in a specific case阻止第二个实例运行,除非在特定情况下
【发布时间】:2008-12-27 21:28:20
【问题描述】:

好的,我有这个程序,我不想运行多个实例。所以我现在拥有的是它会抓取与其名称匹配的所有实例,如果有多个实例,它会退出并让用户知道它已经在另一个实例中运行。

但是,有一种特殊情况,新实例想要更改另一个实例正在执行的操作,然后它将退出。我该怎么做?

这是一个例子: 我有一个计时事件的程序。我不希望同时运行多个,因为你不能同时做两件事(对于这个应用程序)。现在假设第三方程序想要通知该线程用户正在处理其他事情,因此它再次启动应用程序。如果应用程序已经在运行,它将更新其操作,否则它将正常运行。

如何做到这一点?

这是我用来判断是否有另一个实例正在运行的:

            string proc = Process.GetCurrentProcess().ProcessName;

            Process[] processess = Process.GetProcessesByName(proc);
            if (processess.Length > 1) {
                MessageBox.Show("There is an instance of the Timer already running");
                return;
            }

【问题讨论】:

    标签: c# multithreading process


    【解决方案1】:

    使这变得复杂的事实是,在某些情况下,如果另一个程序正在运行,您希望允许该程序的第二次调用来执行某些操作。使用命名互斥体将允许您检测程序是否已经在运行——它应该已经持有互斥体。您仍然需要一种与之通信的方法,以告诉正在运行的程序在第二个程序运行时执行某些操作。异步消息队列可能会起作用,您只需要让正在运行的程序定期检查它以查看是否有任何新消息在等待。该消息需要告诉程序如何更改。查看System.Threading 命名空间(因为看起来您已经在使用.Net),特别是互斥量和信号量类,以及用于消息交换的System.Messaging.MessageQueue

    基本思路是:

      program start
      try to acquire mutex (or semaphore)
      if failed
         send message via message queue to running program
         exit
      else
    
      set up listener for message queue
    
      run rest of program
    

    侦听器可以采用定时器的形式定期到期,到期回调检查队列中的消息并相应地更新程序操作。计时器需要自动重置,以便重新开始收听。您的程序将需要能够从被计时器中断中恢复并根据更新的配置“重新启动”。

    【讨论】:

    • 命名管道不应该能够处理消息吗?
    • 我想是的,还没有真正考虑过。
    【解决方案2】:

    您可以为此使用共享(命名)互斥锁。

    请参阅Win32 API documentation for Mutex objects(我假设 C# 对此有语言绑定)。

    【讨论】:

    • 查看我更新的答案...我假设您在 Windows 上运行。其他操作系统也有类似的 IPC 服务。
    【解决方案3】:

    最好的办法是使用 Mutex 进行检测,然后通过 IPCChannel 使用非常简单的远程处理。

    只需要 1 个 MarshalByRefObject 类并在最初启动应用程序时启动远程服务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 2020-01-26
      • 2021-08-23
      • 2010-11-12
      • 2022-08-19
      • 1970-01-01
      • 2013-03-24
      相关资源
      最近更新 更多