В попытке избавить мой GUI от условий гонки и взаимных блокировок у меня есть следующая функция, которую я вызываю из c'tor, и всякий раз, когда мне нужна служба, которая использует мое именованное имя mutex
, чтобы предоставить свой ввод:
void EnvCapt::FireServiceAndOrHold() {
try {
mutTimerSyncEx->ReleaseMutex();
Thread::Sleep(100); //Time enough for the service to complete.
if (!mutTimerSyncEx->WaitOne(3 * int_ms)) {//int_ms = the polling period
//Must've been doubly locked or worse.
mutTimerSyncEx->ReleaseMutex();
FireServiceAndOrHold();
}
} catch (Exception ^ ex) {
//Released unheld mutex. Retake control.
mutTimerSyncEx->WaitOne();
FireServiceAndOrHold();
}
}
Это работает относительно хорошо, но я звоню по этому поводу, прежде чем позволить службе, теперь я готов принять ввод, поэтому он никогда не пытается ждать, пока я не отпущу мьютекс для него. Прежде чем я попытаюсь изменить порядок вещей, я хотел бы знать, что происходит с вышеуказанной функцией. Я получаю ошибку:
Метод синхронизации объектов был вызван из несинхронизированного блока кода.
Потому что, вызывая release для mutex
, который не был WaitOne
, бросил, я поймал это, зная, что я свободен, чтобы получить право собственности на него и продолжить. Но я не прав. Он навсегда зависает от оператора WaitOne()
. Я знаю, что другой процесс делает все это время, потому что он заперт в моем втором окне отладчика. Это не касается мьютекса.
UPDATE
Я попытался изменить порядок, который я впервые предложил, это казалось хорошим, но теперь я обнаружил, что мьютекс - это всего лишь глобальный тип, несмотря на глобальное \ имя.
Это является общим, потому что когда мой GUI c'tor's, то firstInstance
ложно, поэтому я пытаюсь взять его под контроль.
Это не общий доступ, потому что когда GUI вызывает WaitOne()
, GUI блокируется на неопределенный срок. Принимая во внимание, что служба танцует прямо через WaitOne()
без заботы в мире.