Object synchronization method was called from an unsynchronized block of code
От: e.thrash  
Дата: 25.05.19 13:56
Оценка:
При выполнение кода ниже кидается ошибка из сабжа.
Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?

static void Main(string[] args)
        {
            var appGuid = $"Global\\{Assembly.GetExecutingAssembly().GetType().GUID.ToString()}";
            Mutex namedMutex;
            try
            {
                namedMutex = Mutex.OpenExisting(appGuid);
            }
            catch (WaitHandleCannotBeOpenedException w)
            {
                namedMutex = new Mutex(false, appGuid);
            }

            Task t = new Task(() => { Console.WriteLine("aaa"); });
            t.Start();
            t.Wait();
        
            namedMutex.ReleaseMutex();;

        }


добавил. Насколько это правильно?
           namedMutex.WaitOne();
            namedMutex.ReleaseMutex();;
Re: Object synchronization method was called from an unsynchronized block of cod
От: Egorio Россия  
Дата: 25.05.19 14:18
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>При выполнение кода ниже кидается ошибка из сабжа.

ET>Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?

ET>
ET>static void Main(string[] args)
ET>        {
ET>            var appGuid = $"Global\\{Assembly.GetExecutingAssembly().GetType().GUID.ToString()}";
ET>            Mutex namedMutex;
ET>            try
ET>            {
ET>                namedMutex = Mutex.OpenExisting(appGuid);
ET>            }
ET>            catch (WaitHandleCannotBeOpenedException w)
ET>            {
ET>                namedMutex = new Mutex(false, appGuid);
ET>            }

ET>            Task t = new Task(() => { Console.WriteLine("aaa"); });
ET>            t.Start();
ET>            t.Wait();
        
ET>            namedMutex.ReleaseMutex();;

ET>        }
ET>


ET>добавил. Насколько это правильно?

ET>
ET>           namedMutex.WaitOne();
ET>            namedMutex.ReleaseMutex();;
ET>


Текст ошибки прикрепите
Re[2]: Object synchronization method was called from an unsynchronized block of
От: e.thrash  
Дата: 26.05.19 04:45
Оценка:
Здравствуйте, Egorio, Вы писали:

E>Здравствуйте, e.thrash, Вы писали:


Object synchronization method was called from an unsynchronized block of cod


ET>>При выполнение кода ниже кидается ошибка из сабжа.

ET>>Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?

ET>>
ET>>static void Main(string[] args)
ET>>        {
ET>>            var appGuid = $"Global\\{Assembly.GetExecutingAssembly().GetType().GUID.ToString()}";
ET>>            Mutex namedMutex;
ET>>            try
ET>>            {
ET>>                namedMutex = Mutex.OpenExisting(appGuid);
ET>>            }
ET>>            catch (WaitHandleCannotBeOpenedException w)
ET>>            {
ET>>                namedMutex = new Mutex(false, appGuid);
ET>>            }

ET>>            Task t = new Task(() => { Console.WriteLine("aaa"); });
ET>>            t.Start();
ET>>            t.Wait();
        
ET>>            namedMutex.ReleaseMutex();;

ET>>        }
ET>>


ET>>добавил. Насколько это правильно?

ET>>
ET>>           namedMutex.WaitOne();
ET>>            namedMutex.ReleaseMutex();;
ET>>


E>Текст ошибки прикрепите
Re: Object synchronization method was called from an unsynchronized block of cod
От: hi_octane Беларусь  
Дата: 26.05.19 07:23
Оценка: +2
ET>Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?

Ошибка говорит что делать ReleaseMutex() можно только тому мьютексу который захвачен. Так как он у тебя не захвачен, то ReleaseMutex() явная ошибка.

По факту у тебя мьютекс ничего не защищает. Просто создаётся и всё. Конструирование мьютекса != его захвату.

ET>добавил. Насколько это правильно?

ET>
ET>           namedMutex.WaitOne();
ET>            namedMutex.ReleaseMutex();;
ET>


Тут ты устранил сообщение об ошибке — теперь код между WaitOne() и ReleaseMutex() будет защищён. Но все вот эти Task, Start, Wait — не будут.

Вообще ReleaseMutex() обычно ставят в finally, а то вдруг какая ошибка в коде и получишь вечную блокировку.
Re[2]: Object synchronization method was called from an unsynchronized block of
От: e.thrash  
Дата: 26.05.19 09:15
Оценка:
Здравствуйте, hi_octane, Вы писали:

ET>>Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?


_>Ошибка говорит что делать ReleaseMutex() можно только тому мьютексу который захвачен. Так как он у тебя не захвачен, то ReleaseMutex() явная ошибка.


_>По факту у тебя мьютекс ничего не защищает. Просто создаётся и всё. Конструирование мьютекса != его захвату.


ET>>добавил. Насколько это правильно?

ET>>
ET>>           namedMutex.WaitOne();
ET>>            namedMutex.ReleaseMutex();;
ET>>


_>Тут ты устранил сообщение об ошибке — теперь код между WaitOne() и ReleaseMutex() будет защищён. Но все вот эти Task, Start, Wait — не будут.


_>Вообще ReleaseMutex() обычно ставят в finally, а то вдруг какая ошибка в коде и получишь вечную блокировку.


у меня задача мьютекса — не допустить запуска 2 экземпляров приложений.
Таски защищены в другом месте.
То есть в таком варианте код нормальный?
Re[3]: Object synchronization method was called from an unsynchronized block of
От: hi_octane Беларусь  
Дата: 26.05.19 13:34
Оценка:
ET>То есть в таком варианте код нормальный?
Пока выглядит так будто сигналом о запущенном экземпляре является само существование мьютекса. Но где тогда return из блока try?
В любом случае по уму сигналом о том что запускаемый инстанс первый и единственный — должен быть именно захват мьютекса. Соответственно его надо попытаться захватить сразу после создания/открытия и держать всё время пока запущено приложение.
Re[3]: Object synchronization method was called from an unsy
От: bnk СССР http://unmanagedvisio.com/
Дата: 26.05.19 14:06
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>у меня задача мьютекса — не допустить запуска 2 экземпляров приложений.

ReleaseMutex не нужен, try/catch тоже, у Mutext же есть нужный конструктор. Имя у тебя тоже что-то замысловатое, почему бы попроще констату не использовать?

    static void Main(string[] args)
    {
        var namedMutex = new Mutex(true, $"e.trash-100500", out var createdNew);
        if (!createdNew)
            return; // already running
Отредактировано 26.05.2019 14:12 bnk . Предыдущая версия .
Re[4]: Object synchronization method was called from an unsy
От: e.thrash  
Дата: 28.05.19 06:13
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Здравствуйте, e.thrash, Вы писали:


ET>>у меня задача мьютекса — не допустить запуска 2 экземпляров приложений.

bnk>ReleaseMutex не нужен, try/catch тоже, у Mutext же есть нужный конструктор. Имя у тебя тоже что-то замысловатое, почему бы попроще констату не использовать?

bnk>
bnk>    static void Main(string[] args)
bnk>    {
bnk>        var namedMutex = new Mutex(true, $"e.trash-100500", out var createdNew);
bnk>        if (!createdNew)
bnk>            return; // already running
bnk>


Раньше также делал.
После прочтения "Pro .NET 4 Parallel Programming in C#" стал использовать как указал.
Но вопрос о другом.

namedMutex.WaitOne();

это решение проблемы в моем случае или Релизить мьютекс не надо и он сам кильнется после завершения?

Пример из книги

// declare the name we will use for the mutex
string mutexName = "myApressMutex";
// declare the mutext
Mutex namedMutext;
try {
// test to see if the named mutex already exists
namedMutext = Mutex.OpenExisting(mutexName);
} catch (WaitHandleCannotBeOpenedException) {
// the mutext does not exist - we must create it
namedMutext = new Mutex(false, mutexName);
}
Re[5]: Object synchronization method was called from an unsy
От: bnk СССР http://unmanagedvisio.com/
Дата: 28.05.19 11:32
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>>>у меня задача мьютекса — не допустить запуска 2 экземпляров приложений.

bnk>>ReleaseMutex не нужен, try/catch тоже, у Mutext же есть нужный конструктор. Имя у тебя тоже что-то замысловатое, почему бы попроще констату не использовать?

bnk>>
bnk>>    static void Main(string[] args)
bnk>>    {
bnk>>        var namedMutex = new Mutex(true, $"e.trash-100500", out var createdNew);
bnk>>        if (!createdNew)
bnk>>            return; // already running
bnk>>


ET>Раньше также делал.

ET>После прочтения "Pro .NET 4 Parallel Programming in C#" стал использовать как указал.

Может автор не в курсе про этот (IMHO, более простой) способ? Или есть какая-то конкретная причина делать сложно?

ET>Но вопрос о другом.

ET>

ET> namedMutex.WaitOne();

ET>это решение проблемы в моем случае или Релизить мьютекс не надо и он сам кильнется после завершения?

ReleaseMutex не удаляет мьютекс, а снимает с него блокировку (разрешает другим его захватывать).
У тебя же фейлится вроде потому, что твой мьютекс никто не захватывал, а ты его пытаешься освободить?

А вообще все хэндлы освобождаются операционкой при завершении процесса.
Т.к. мьютекс — обертка над хэндлом, он "удалится" при завершении процесса.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.