При отладке приложения, использующего семафоры для межпроцессной синхронизации, я наткнулся на идею использования PowerShell вместо «другого» процесса. Выполнение чего-то подобного в PowerShell работает нормально:
// In C# application:
var sem = new Semaphore(0, 1, "CrossProcSem");
sem.WaitOne();
# In PowerShell session:
[1] C:\Projects $ $sem = New-Object System.Threading.Semaphore(0, 1, "CrossProcSem")
[2] C:\Projects $ $sem.Release()
И я могу повторно вызывать WaitOne()
и Release()
в одном и том же экземпляре семафора, так часто, как мне нужно.
Но когда я пытаюсь сделать то же самое с Mutex, PowerShell продолжает утверждать, что мьютекс был заброшен:
[1] C:\Projects $ $mtx = New-Object System.Threading.Mutex($false, "CrossProcMtx")
[2] C:\Projects $ $mtx.WaitOne()
True
[3] C:\Projects $ $mtx.ReleaseMutex()
[4] C:\Projects $ $mtx.WaitOne()
Exception calling "WaitOne" with "0" argument(s): "The wait completed due to an abandoned mutex."
At line:1 char:13
+ $mtx.WaitOne <<<< ()
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : DotNetMethodException
Ошибка, кажется, возникает всякий раз, когда я вызываю WaitOne()
после того, как один раз получил мьютекс, либо предыдущий вызов WaitOne
, либо запрос на его первоначальное владение в конструкторе:
[5] C:\Projects $ $mtx2 = New-Object System.Threading.Mutex($true)
[6] C:\Projects $ $mtx2.WaitOne()
Exception calling "WaitOne" with "0" argument(s): "The wait completed due to an abandoned mutex."
At line:1 char:14
+ $mtx2.WaitOne <<<< ()
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : DotNetMethodException
[7] C:\Projects $ $mtx3 = New-Object System.Threading.Mutex
[8] C:\Projects $ $mtx3.WaitOne()
True
[9] C:\Projects $ $mtx3.WaitOne()
Exception calling "WaitOne" with "0" argument(s): "The wait completed due to an abandoned mutex."
At line:1 char:14
+ $mtx3.WaitOne <<<< ()
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : DotNetMethodException
Powershell выполняет какие-то странные махинации в фоновом режиме или я просто полностью забыл, как работают мьютексы?