Is there anything except for Mutex to synchronise two processes in a fault-tolerant fashion? Please bear with me...
There is a process A, it's a bit flaky, it needs to start process B in the background and continue. If process A successfully does its thing, it needs to signal process B to dispose, and moves on (it doesn't terminate and thread is reused). If process A dies due to exception, termination, etc. process B needs to detect it quickly and dispose of itself on its own. Process A is not a "process" rather a library executed by various hosts hence process B can't just wait for process A's name to disappear.
Enter Mutex.
Here process A represented by a test fixture, if successful it'll call TestFixtureTearDown and move on, or test runner might be killed and TestFixtureTearDown is never executed. As with the actual process, TestFixtureTearDown might be called by a different thread to one that ran TestFixtureSetUp and created the mutex, hence ReleaseMutex sometimes throws ApplicationException : Object synchronization method was called from an unsynchronized block of code.
Can I force
ReleaseMutexinTestFixtureTearDownif it's being executed by a different thread or abandon mutex some other way?Is there an alternative to Mutex that I can use for such fault-tolerant "reverse" wait/monitor scenario? Preferably without implementing process A sending heartbeats to process B and process B tracking intervals and timing out? Mutex felt like such an elegant solution except for occasional
ApplicationExceptionon asyncs.
.
namespace ClassLibrary1 { public class Class1 { private Mutex _mutex; private Process _process; [TestFixtureSetUp] public void TestFixtureSetUp() { _mutex = new Mutex(true, "foo"); _process = Process.Start("ConsoleApplication1.exe"); } [Test] public void Test1() { /* Do stuff */ } [Test] public void Test2() { /* Do async stuff */ } [TestFixtureTearDown] public void TestFixtureTearDown() { _mutex.ReleaseMutex(); _process.WaitForExit(); } } } .
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var mutex = Mutex.OpenExisting("foo"); // Start doing stuff try { mutex.WaitOne(); } catch (AbandonedMutexException) { } finally { mutex.ReleaseMutex(); } // Finish doing stuff } } }