public void TestDomainAttachDetach()
{
var attachedEvent = new ManualResetEvent(false);
var detachedEvent = new ManualResetEvent(false);
using (var domain = ProcessDomain.CreateDomain("ProcessDomain"))
{
domain.Attached += () => attachedEvent.Set();
domain.Detached += () => detachedEvent.Set();
var obj = (RemoteTestObject)domain.CreateInstanceAndUnwrap(TestObjectAssemblyName, TestObjectTypeName);
Assert.That(!attachedEvent.WaitOne(0));
Assert.That(!detachedEvent.WaitOne(0));
// restart should occur, but our current object will be invalid
Process.GetProcessById(obj.GetProcessId()).Kill();
Assert.That(detachedEvent.WaitOne(10000), "Timed-out waiting for process to die");
Assert.That(attachedEvent.WaitOne(10000), "Timed-out waiting for process to respawn");
Assert.Throws<RemotingException>(() => obj.GetProcessId());
// create object in restarted domain
obj = (RemoteTestObject)domain.CreateInstanceAndUnwrap(TestObjectAssemblyName, TestObjectTypeName);
Assert.That(obj.GetProcessId(), Is.Not.EqualTo(Process.GetCurrentProcess().Id));
}
var setupInfo = new ProcessDomainSetup
{
RestartOnProcessExit = false
};
// now restart should not occur
using (var domain = ProcessDomain.CreateDomain("RemoteProcess2", setupInfo))
{
domain.Attached += () => attachedEvent.Set();
domain.Detached += () => detachedEvent.Set();
var obj = (RemoteTestObject)domain.CreateInstanceAndUnwrap(TestObjectAssemblyName, TestObjectTypeName);
Assert.That(obj.GetProcessId(), Is.Not.EqualTo(Process.GetCurrentProcess().Id));
attachedEvent.Reset();
detachedEvent.Reset();
Process.GetProcessById(obj.GetProcessId()).Kill();
Assert.That(detachedEvent.WaitOne(10000), "Timed-out waiting for process to die");
Assert.That(!attachedEvent.WaitOne(5000), "Unexpected re-attach");
Assert.Throws<RemotingException>(() => obj.GetProcessId());
Assert.Throws<RemotingException>(() => obj = (RemoteTestObject)domain.CreateInstanceAndUnwrap(TestObjectAssemblyName, TestObjectTypeName));
}
}