如何检查是否有其他应用程序实例在运行

时间:2013-04-24 18:48:09

标签: c# .net

我已经在C#中编写了一个应用程序,它放在我们的服务器上。 当有人需要使用它时,应用程序直接从服务器启动,从LAN中任何连接的PC启动。

有没有简单的方法来检查正在运行的实例数量?或者更确切地说,如果有任何其他实例而不是我开始的实例?


编辑:

这不是提供的帖子的副本,因为我不想确保只有一个实例正在运行(因为在"不要运行超过1个应用程序同一时间")但要检查,如果我以外的人正在运行它(在正常情况下,它必须在多台PC上同时工作)

3 个答案:

答案 0 :(得分:1)

没有简单的方法可以知道程序的实例在同一个二进制文件的某台机器上运行 - 你的程序需要以某种方式报告“我正在运行”到某个共享位置,而不是检查是否有其他实例运行

如果您只需要检查单个实例,则可以从同一位置打开文件,如果多个实例尝试打开它,它将会失败。

共享位置的耦合选项以计算实例:

  • 使用机器名称
  • 更新某个文件
  • 一些要ping的网络服务/网站
  • 共享数据库

请注意,这也意味着如果程序死亡,共享位置中可能没有关于此特定实例的报告已完成。

答案 1 :(得分:0)

有几种方法可以做,例如,使用套接字的东西,数据库。最简单的方法(但不安全)可能是使用文件来记录实例的数量,您可能想要改进它。

void WriteToFile(int x, int millisecondsTimeout) {
    for(; ; Thread.Sleep(millisecondsTimeout))
        try {
            using(var file=File.Open("instances.bin", FileMode.OpenOrCreate)) {
                var bytes=new byte[sizeof(int)];
                file.Read(bytes, 0, sizeof(int));
                var instances=x+BitConverter.ToInt32(bytes, 0);

                if(instances>-1)
                    file.Write(BitConverter.GetBytes(instances), 0, sizeof(int));

                break;
            }
        }
        catch(IOException ex) {
        }
}

void Increment() { // invoke on program starts
    WriteToFile(1, 1000);
}

void Decrement() { // invoke on program exits
    WriteToFile(-1, 1000);
}

请注意,文件"instances.bin"应该是位于服务器上的文件。

一旦程序意外终止,您可能还想编写AppDomain.CurrentDomain.UnhandledException处理程序。

答案 2 :(得分:0)

通常,要仅允许应用程序的N个并发实例,您可以使用命名信号量,因为它们在整个系统中可见。

启动应用程序时,尝试使用指定允许的实例数的参数创建一个名为Semaphore的命令。如果WaitOne失败,则表示所有实例都在使用中,因此您退出应用程序。

这是示例代码(我的头脑,掩盖了一些微妙的问题,没有错误处理等)

    const int MAX_INSTANCES = 2; // set desired number of concurrent instances
    var s = new Semaphore(MAX_INSTANCES, MAX_INSTANCES, "unique_name_of_semaphore");
    if (s.WaitOne(0)) // zero timeout - exit immediately if exhausted
    {
      // good, we're in, run the app
      Application.Run(new Form()); // run the app - a winforms example
      s.Release();   // release the semaphore
    }
    else
    {
      // oops, exhausted:
      MessageBox.Show("too many instances running !!");
    }

您还可以使用Semaphore.OpenExisting()变体,具体取决于您的应用需求。

编辑:oops,只是注意到你实际上并不需要这个但是要验证在不同机器上运行的实例 - 如果没有向服务器报告的机制,这就更难了。