قم بتشغيل مثيل واحد للتطبيق باستخدام Mutex

StackOverflow https://stackoverflow.com/questions/819773

  •  03-07-2019
  •  | 
  •  

سؤال

من أجل السماح بمثيل واحد فقط لتطبيق يعمل على استخدام Mutex. وفيما يلي التعليمات البرمجية. هل هذه هي الطريقة الصحيحة للقيام بذلك؟ هل هناك أي عيوب في الكود؟

كيفية إظهار التطبيق الذي يتم تشغيله بالفعل عندما يحاول المستخدم فتح التطبيق في المرة الثانية. في الوقت الحالي (في الكود أدناه) ، أنا فقط أعرض رسالة تفيد بأن مثيلًا آخر قيد التشغيل بالفعل.

    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");

        }            
    }
هل كانت مفيدة؟

المحلول

لقد فعلت ذلك بهذه الطريقة مرة واحدة ، آمل أن يساعد ذلك:

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;
}

نصائح أخرى

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

انا استعمل هذا:

    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();
        }
    }    

القي نظرة على هذا السؤال

هناك رابط لهذه المقالة: يسيء الفهم mutex حيث يتم شرح استخدام mutex.

تحقق من عينة الكود الموضحة في هذه الصفحة

باختصار ، يمكنك استخدام Mutex الزائد ctor(bool, string, out bool) الذي يخبرك عبر معلمة خارج ، سواء حصلت على ملكية Mutex المسماة. إذا كنت الحالة الأولى ، فسيحتوي هذا على TRUE بعد أن يتم استدعاء CTOR - وفي هذه الحالة تتابع كالمعتاد. إذا كانت هذه المعلمة خاطئة ، فهذا يعني أن هناك مثيلًا آخر قد حصل بالفعل على ملكية/يعمل ، وفي هذه الحالة تظهر رسالة خطأ "مثيل آخر يعمل بالفعل". ثم الخروج بأمان.

استخدم التطبيق مع إعدادات المهلة والأمان. لقد استخدمت صفي المخصص:

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");
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top