Search code examples
c#.netmultithreadingappdomainunhandled-exception

Non-deterministic multithread test


I have an extension method. Here it is:

public static void BeginInvokeWithAutoEnd(this EventHandler handler, object sender, EventArgs eventArgs)
{
    var buffer = handler;
    buffer.BeginInvoke(sender, eventArgs, buffer.EndInvoke, null);
}

To test it, there is the following method:

[TestMethod]
public void BeginInvokeWithAutoEnd_SubscribedMethodThrowsException_ExceptionCanBeCaught()
{
    var multiThreadTest = new MultiThreadTest(2);//Class that helps to test asynchronous stuff 
    var thrown = false;
    var ex = new Exception("OOoooOOo!");
    EventHandler onHandler = (s, a) => { throw ex; };
    UnhandledExceptionEventHandler currentDomainOnUnhandledException = (s, args) =>
    {
        thrown = args.ExceptionObject.Equals(ex);
        multiThreadTest.Notify();
    };
    AppDomain.CurrentDomain.UnhandledException += currentDomainOnUnhandledException;

    //Invokes Action from the parameter and waits for multiThreadTest.Notify(); method to be called, otherwise 2 seconds
    multiThreadTest.Act(() => onHandler.BeginInvokeWithAutoEnd(this, EventArgs.Empty));

    AppDomain.CurrentDomain.UnhandledException -= currentDomainOnUnhandledException;
    Assert.IsTrue(thrown);
}

The test itself works fine, but it breaks randomly one of other tests I have. When I look at the broken test it is written: The agent process was stopped while the test was running.. That means that there was an unhandled exception in another thread, while the broken test was running.

I have no idea how could this happen. Will appreciate any help here.


Solution

  • It was so stupid of me.

    Workflow of the test:
    -the test is started
    -the exception is thrown in another thread (let's call it "Thread X")
    -AppDomain.CurrentDomain.UnhandledException is raised
    -the test finishes, while "Thread X" still runs and haven't finished throwing exception yet
    -"Thread X" throws the exception, while another test is already started

    For some unknown reason I thought that subscribing to AppDomain.CurrentDomain.UnhandledException will prevent the exception from being thrown. So really stupid of me.