При выполнение кода ниже кидается ошибка из сабжа.
Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?
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
Здравствуйте, e.thrash, Вы писали:
ET>При выполнение кода ниже кидается ошибка из сабжа. ET>Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?
ET>
Здравствуйте, Egorio, Вы писали:
E>Здравствуйте, e.thrash, Вы писали:
Object synchronization method was called from an unsynchronized block of cod
ET>>При выполнение кода ниже кидается ошибка из сабжа. ET>>Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?
ET>>
Здравствуйте, hi_octane, Вы писали:
ET>>Нашел описание проблемы, но по русски кто может рассказать почему данный код кидает ошибку при релизе мьюеткса?
_>Ошибка говорит что делать ReleaseMutex() можно только тому мьютексу который захвачен. Так как он у тебя не захвачен, то ReleaseMutex() явная ошибка.
_>По факту у тебя мьютекс ничего не защищает. Просто создаётся и всё. Конструирование мьютекса != его захвату.
ET>>добавил. Насколько это правильно? ET>>
_>Тут ты устранил сообщение об ошибке — теперь код между WaitOne() и ReleaseMutex() будет защищён. Но все вот эти Task, Start, Wait — не будут.
_>Вообще ReleaseMutex() обычно ставят в finally, а то вдруг какая ошибка в коде и получишь вечную блокировку.
у меня задача мьютекса — не допустить запуска 2 экземпляров приложений.
Таски защищены в другом месте.
То есть в таком варианте код нормальный?
Re[3]: Object synchronization method was called from an unsynchronized block of
ET>То есть в таком варианте код нормальный?
Пока выглядит так будто сигналом о запущенном экземпляре является само существование мьютекса. Но где тогда return из блока try?
В любом случае по уму сигналом о том что запускаемый инстанс первый и единственный — должен быть именно захват мьютекса. Соответственно его надо попытаться захватить сразу после создания/открытия и держать всё время пока запущено приложение.
Re[3]: Object synchronization method was called from an unsy
Здравствуйте, 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
Здравствуйте, 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 mutexstring 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
Здравствуйте, 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 не удаляет мьютекс, а снимает с него блокировку (разрешает другим его захватывать).
У тебя же фейлится вроде потому, что твой мьютекс никто не захватывал, а ты его пытаешься освободить?
А вообще все хэндлы освобождаются операционкой при завершении процесса.
Т.к. мьютекс — обертка над хэндлом, он "удалится" при завершении процесса.