代码之家  ›  专栏  ›  技术社区  ›  blitzkriegz

使用互斥锁运行应用程序的单个实例

  •  22
  • blitzkriegz  · 技术社区  · 17 年前

    为了只允许运行应用程序的单个实例,我使用了互斥锁。代码如下所示。这样做对吗?代码中有缺陷吗?

    如何在用户第二次尝试打开应用程序时显示已在运行的应用程序。目前(在下面的代码中),我只是显示一条消息,说明另一个实例已经在运行。

        static void Main(string[] args)
        {
            Mutex _mut = null;
    
            try
            {
                _mut = Mutex.OpenExisting(AppDomain.CurrentDomain.FriendlyName);
            }
            catch
            {
                 //handler to be written
            }
    
            if (_mut == null)
            {
                _mut = new Mutex(false, AppDomain.CurrentDomain.FriendlyName);
            }
            else
            {
                _mut.Close();
                MessageBox.Show("Instance already running");
    
            }            
        }
    
    7 回复  |  直到 11 年前
        1
  •  12
  •   Peter D    17 年前

    我曾经这样做过一次,我希望它能有帮助:

    bool createdNew;
    
    Mutex m = new Mutex(true, "myApp", out createdNew);
    
    if (!createdNew)
    {
        // myApp is already running...
        MessageBox.Show("myApp is already running!", "Multiple Instances");
        return;
    }
    
        2
  •  7
  •   Milen    17 年前
    static void Main() 
    {
      using(Mutex mutex = new Mutex(false, @"Global\" + appGuid))
      {
        if(!mutex.WaitOne(0, false))
        {
           MessageBox.Show("Instance already running");
           return;
        }
    
        GC.Collect();                
        Application.Run(new Form1());
      }
    }
    

    来源: http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

        3
  •  3
  •   algreat    13 年前

    我用这个:

        private static Mutex _mutex;
    
        private static bool IsSingleInstance()
        {
            _mutex = new Mutex(false, _mutexName);
    
            // keep the mutex reference alive until the normal 
            //termination of the program
            GC.KeepAlive(_mutex);
    
            try
            {
                return _mutex.WaitOne(0, false);
            }
            catch (AbandonedMutexException)
            {
                // if one thread acquires a Mutex object 
                //that another thread has abandoned 
                //by exiting without releasing it
    
                _mutex.ReleaseMutex();
                return _mutex.WaitOne(0, false);
            }
        }
    
    
        public Form1()
        {
            if (!isSingleInstance())
            {
                MessageBox.Show("Instance already running");
                this.Close();
                return;
            }
    
            //program body here
        }
    
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_mutex != null)
            {
                _mutex.ReleaseMutex();
            }
        }    
    
        4
  •  1
  •   Community Mohan Dere    9 年前

    看一看 this question

    这篇文章有一个链接: the misunderstood mutex 其中解释了互斥锁的用法。

        5
  •  1
  •   Gishu    17 年前

    查看上显示的代码示例 this page

    简而言之,使用重载互斥锁 ctor(bool, string, out bool) 它通过out参数告诉您是否拥有命名互斥锁。如果您是第一个实例,那么这个out参数在调用ctor之后将包含true—在这种情况下,您将照常进行。如果此参数为false,则表示另一个实例已获得所有权/正在运行,在这种情况下,将显示错误消息“另一个实例已在运行”。然后优雅地退出。

        6
  •  1
  •   vivlav    11 年前

    使用带有超时和安全设置的应用程序。我用了我的定制课程:

    private class SingleAppMutexControl : IDisposable
        {
            private readonly Mutex _mutex;
            private readonly bool _hasHandle;
    
            public SingleAppMutexControl(string appGuid, int waitmillisecondsTimeout = 5000)
            {
                bool createdNew;
                var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                    MutexRights.FullControl, AccessControlType.Allow);
                var securitySettings = new MutexSecurity();
                securitySettings.AddAccessRule(allowEveryoneRule);
                _mutex = new Mutex(false, "Global\\" + appGuid, out createdNew, securitySettings);
                _hasHandle = false;
                try
                {
                    _hasHandle = _mutex.WaitOne(waitmillisecondsTimeout, false);
                    if (_hasHandle == false)
                        throw new System.TimeoutException();
                }
                catch (AbandonedMutexException)
                {
                    _hasHandle = true;
                }
            }
    
            public void Dispose()
            {
                if (_mutex != null)
                {
                    if (_hasHandle)
                        _mutex.ReleaseMutex();
                    _mutex.Dispose();
                }
            }
        }
    

    并使用它:

        private static void Main(string[] args)
        {
            try
            {
                const string appguid = "{xxxxxxxx-xxxxxxxx}";
                using (new SingleAppMutexControl(appguid))
                {
    
                    Console.ReadLine();
                }
            }
            catch (System.TimeoutException)
            {
                Log.Warn("Application already runned");
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Fatal Error on running");
            }
        }