locked
FAQs:如何确保我的程序里的一个实例只运行一次? RRS feed

  • 问题

  • 为了帮助大家更好地学习 .Net Framework 技术,微软论坛技术支持团队编辑了一些列的 ".Net Framework 常见问题及解答" 精华帖。

    本帖的主题是:如何确保我的程序里的一个实例只运行一次?

    如果您觉得这个帖子对您的学习、工作有所帮助,请再把这个帖子分享给你的同学、同事和朋友。

    如果您想阅读更多的 ".Net Framework 常见问题及解答",请打开索引页面:
    http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/b8c520b0-3ae8-4129-88a6-6221863a09c4


    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。

     

     

    2011年2月28日 2:20

答案

  • 完成这个最好的方法是使用一个名字叫做Mutex的类。

    bool  firstInstance;

    Mutex  mutex=new Mutex(false,  “Local\\” + someUniqueName, out firststance);

    //如果firstInstancetrue的话,我们的程序现在运行的是第一个实例,否则另外一个实//例在运行。

    注意互斥体(Mutex)是本地的,这就意味着它在当前用户的会话里。不在本地的部分,其他用户将共享此Mutex,所以两个不同用户不能在同一时间运行程序。此外请注意(不同于网络上的各种例子)我的代码不会去调用ReleaseMutex。这是因为进程结束的时候,会自动释放互斥体(Mutex),这是要求的行为。

    还要注意的一点是互斥体(Mutex)不会被垃圾回收(Garbage Collected)。如果一个局部变量仅仅在一个方法开始的附近使用,当计算出这些变量是垃圾回收(GC)的根(root)的时候,垃圾回收(GC)会忽略它们。如果这样的话,这个方法的一部分已经执行了。这样导致你会比预期早释放Mutex(互斥体)。为了防止这种情况发生,在你的main方法最后调用GC.KeepAlivemutex)。或者你可以使用一个静态变量来存放互斥体(Mutex)。这样将确保互斥体(Mutex)在应用程序域卸载(AppDomain)之后回收掉。(使用这种方式,甚至main方法结束了,如果你已经有其他线程在执行,你也不会碰到任何问题的。)

    解决这个问题(其中带有自己的问题)的另外的方法是在本地端口侦听。只有一个进程可以在特定的端口侦听,这将确保你的程序的任何其他实例正在运行。但是如果另一应用程序也要使用该端口,你的应用程序将认为有另一实例运行,或者其他应用程序无法运行。

    注意这种方式提供了mian实例和新创建实例之间交流的的好处。例如:如果新创建的实例想要main实例去打开用户请求的一个文件,可以使用socket

    有关的帖子:

    一个程序实例:

    http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/70aaeed6-6d97-4627-bcbe-9766679f8caf/

    如何只有一个或者复制的一个应用程序运行?

    http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/5370ddb4-9b80-4427-9f41-33f345335350/

    只允许一个程序的实例

    http://social.msdn.microsoft.com/forums/en/netfxbcl/thread/8110c492-de5d-4ba3-a8fd-931a66a069a1/

    如何阻止程序的再次运行如果这个程序已经在运行中?http://social.msdn.microsoft.com/forums/en/netfxbcl/thread/249f1978-aa66-495f-95bc-03461ba647c3/


    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    2011年2月28日 2:21