Используйте общесистемный Mutex - PullRequest
0 голосов
/ 07 марта 2019

У меня есть вопрос, когда речь идет о создании "System Wide Mutex", который будет работать со многими экземплярами одного и того же приложения.

Итак, я хочу, чтобы процесс был потокобезопасным, как видно из кода, в котором я пишу в тот же файл:
Записать в тот же файл

Интересно, правильно ли я настроил это на программном уровне? Например, я освобождаю мьютекс, когда закрываю форму. Я также установил для bool значение true (InitiallyOwned) для мьютекса, когда я его создаю?

Я пытался гуглить, но не уверен, что получил правильный ответ. Сценарий использования будет иметь возможность открывать и закрывать экземпляры в произвольном порядке и всегда иметь мьютекс на месте.

public Form1()
{
    try
    {
        _mutex = System.Threading.Mutex.OpenExisting("systemWideMutex");
        _mutex.WaitOne(); //obtain a lock by waitone
        _mutex.ReleaseMutex(); //release
    }
    catch { _mutex = new System.Threading.Mutex(true, "systemWideMutex"); } //Create mutex for the first time

    new Thread(threadSafeWorkBetween2Instances).Start(); //Start process
}
void threadSafeWorkBetween2Instances()
{
    while (true)
    {
        try
        {
            _mutex = System.Threading.Mutex.OpenExisting("systemWideMutex");
            _mutex.WaitOne(); //obtain a lock by waitone

            //DO THREADSAFE WORK HERE!!!
            //Write to the same file

            _mutex.ReleaseMutex(); //release
        }
        catch { _mutex = new System.Threading.Mutex(true, "systemWideMutex"); } //Create mutex for the first time
        Thread.Sleep(10000);
    }
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    _mutex.ReleaseMutex(); //release
}

1 Ответ

1 голос
/ 07 марта 2019

Попробуйте что-то вроде этого:

     System.Threading.Mutex _mutex = null;
bool mutexWasCreated = false;
                public Form1()
                {
                    new Thread(threadSafeWorkBetween2Instances).Start();
                }
                void threadSafeWorkBetween2Instances()
                {
                     if(!_mutex.TryOpenExisting("GlobalsystemWideMutex"))
                     {
                        // Create a Mutex object that represents the system
                       // mutex named with
                       // initial ownership for this thread, and with the
                       // specified security access. The Boolean value that 
                       // indicates creation of the underlying system object
                       // is placed in mutexWasCreated.
                         //
                        _mutex = new Mutex(true, "GlobalsystemWideMutex", out 
                         mutexWasCreated, mSec);

                        if(!mutexWasCreated )
                        {
                              //report error
                         }
                     } 
                    while (true)
                    {
                        try
                        {                       
                            bool acquired = _mutex.WaitOne(5000); //obtain a lock - timeout after n number of seconds
                            if(acquired)
                            {   
                               try 
                               {
                                  //DO THREADSAFE WORK HERE!!!
                                  //Write to the same file
                               }
                               catch (Exception e)
                               {

                               }  
                               finally 
                               {
                                  _mutex.ReleaseMutex(); //release
                                  break;
                               }                          
                            }
                            else
                            {
                               Thread.Sleep(1000); // wait for n number of seconds before retrying
                            } 
                        }
                        catch {  } //Create mutex for the first time

                    }
                }
                private void Form1_FormClosing(object sender, FormClosingEventArgs e)
                {
                    try { _mutex.ReleaseMutex(); } catch { } //release
                }
...