0

Here's my simple C# console app:

using System.Diagnostics;
using System.Threading;

public static class Program
{
    public static int Main(string[] args)
    {
        var e = new AutoResetEvent(false);
        ThreadPool.QueueUserWorkItem(state =>
        {
            Process.Start("nonexistent path");
            e.Set();
        });
        e.WaitOne();
        return 0;
    }
}

If I run this program within a debugger, it will hang on shutdown. If I replace the line Process.Start("nonexistent path"); (which throws System.ComponentModel.Win32Exception with throw new System.Exception();, it doesn't hang and the program terminates as expected.

It seems to me that .NET/CLR or the debugger must handle Win32Exception in some special way. Is this expected behaviour?

This is running on .NET/CLR 4.0 where unhandled exceptions on worker threads should terminate the application: this is the case for CLR 2.0 and later (http://msdn.microsoft.com/en-us/library/ms228965.aspx).

UPDATE

So far, I've only been able to reproduce this problem on 32-bit Windows OS's when launching the program from a Cygwin terminal.

Richard Cook
  • 32,523
  • 5
  • 46
  • 71
  • Very strange. I just copied your code and the code ends normally – Paul Sinnema Nov 21 '13 at 20:23
  • You sure removed too much code from the snippet and added to many monkeytails to obfuscate the real issue. [This question](http://stackoverflow.com/questions/16202678/process-start-hangs-when-running-on-a-background-thread/16218470#16218470) is a match. – Hans Passant Nov 21 '13 at 23:56
  • I have removed `@`. This is, however, a fully functional code snippet. – Richard Cook Nov 22 '13 at 15:03

1 Answers1

0

There is another issue: The ManualResetEvent was created unset. Because the background thread fails before it sets the ManualResetEvent, the main thread gets stuck on the @event.WaitOne() statement.

MaMazav
  • 1,773
  • 3
  • 19
  • 33
  • I don't believe that's the case. An unhandled exception thrown on a worker thread should cause the entire process to terminate. – Richard Cook Nov 21 '13 at 20:16
  • I don't know how the ThreadPool.QueueUserWorkItem method treats exception (and it is also not documented in the appropriate page in the MSDN). Anyway when using Tasks the exception is caught by TPL and waiting for some continuation task to throw it in. If no such tasks arrive the exception will be thrown on the Finalizer of the Task object - after a long delay (may be even some minutes). Maybe the case here is similar to the one happens when using Tasks. You can try to throw the exception AFTER setting the event to check this theory. – MaMazav Nov 21 '13 at 21:26