8

I have an issue with VS2010 where the debugger stops with an Unhandled Exception. However, the exception is definitely handled. In fact, if I put code in the catch block, I'll hit it when I press F5. In Debug -> Exceptions, I definitely do not have the "Thrown" checkbox checked, so IMO there is absolutely no reason for the unhandled exception dialog to pop up...

I can't post the exact code, but will work on a sample soon. The basic idea behind the offending code section is that I have a thread that talks to hardware, and if I have an error talking to it, then I throw a HardwareException. The thread is launched with BeginInvoke, and the exception is caught in the callback handler when I call EndInvoke.

When the exception is thrown in the debugger, I get a messagebox that says 'HardwareException not handled by user code". But it is!!!

EDIT -- Well, this is driving me crazy. I've got sample code that is representative of the code I have in my application, and it looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Threading;

namespace ConsoleApplication1
{
    public class HardwareException : ApplicationException
    {
        public HardwareException( string message) : base(message) {}
    }

    class Program
    {
        delegate void HardwareTestDelegate();

        static void Main(string[] args)
        {
            HardwareTestDelegate d = new HardwareTestDelegate( HardwareTestThread);
            d.BeginInvoke( HardwareTestComplete, null);
            while( true);
        }

        static void HardwareTestThread()
        {
            throw new HardwareException( "this is a test");
        }

        static void HardwareTestComplete( IAsyncResult iar)
        {
            try {
                AsyncResult ar = (AsyncResult)iar;
                HardwareTestDelegate caller = (HardwareTestDelegate)ar.AsyncDelegate;
                caller.EndInvoke( iar);
            } catch( Exception ex) {
                Console.WriteLine( "Should see this line without getting an unhandled exception message in the IDE");
            }
        }
    }
}

I throw my HardwareException from the thread, and then handle the exception when EndInvoke is called. I guess Murphy was right, because when I run this sample code, it does what I expect -- i.e. no unhandled exception error message pops up in the IDE!

Dave
  • 14,618
  • 13
  • 91
  • 145
  • Any accompanying code, just to aid us in securing your sanity? – Grant Thomas Apr 11 '11 at 15:16
  • Can you add some sample code here? What is the type of the exception being unhandled? – JaredPar Apr 11 '11 at 15:17
  • Is your catch block causing an exception? – rsbarro Apr 11 '11 at 15:18
  • I'll strip out a code snippet. The catch block is not causing an exception. But if I hit F5 when the unhandled exception pops up, I'll hit the breakpoint in my catch block. It's quite strange. And annoying. – Dave Apr 11 '11 at 15:46
  • Are you sure the message is "unhandled exception" and not "first-chance exception"? – Adrian McCarthy Apr 11 '11 at 16:00
  • @Adrian I've updated my post, but the error I get is "HardwareException not handled by user code". – Dave Apr 11 '11 at 20:51
  • When you say the Debug>Exceptions checkbox is not checked, are you drilling down to the exact exception or just look at the top level check box? – CodeNaked Apr 11 '11 at 20:56
  • @CodeNaked Great point, I am only talking about the top level check box, but I did just drill down and I see that ApplicationException is also unchecked (not sure if that even matters, but the exception thrown is my own called `HardwareException` which inherits from `ApplicationException`) – Dave Apr 12 '11 at 02:33
  • 1
    I should also note that this behavior is consistent across all computers I've tried so far. – Dave Apr 12 '11 at 02:33
  • +1 I am having the same issue with WCF on an Async thread. – makerofthings7 May 31 '11 at 00:36
  • I opened case 111053102422121 with Microsoft – makerofthings7 May 31 '11 at 00:40

2 Answers2

2

Here is the response from Microsoft, case 111053102422121. Allen Weng writes the following:

Analysis:

For your information, CLR will re-throw the exception inside the callback when you call EndInvoke(). Below is a simplified version of EndInvoke():

public object EndInvoke(IAsyncResult asyncResult)
{
    using (new MultithreadSafeCallScope())
    {
        ThreadMethodEntry entry = asyncResult as ThreadMethodEntry;
         ............
        if (entry.exception != null)
        {
            throw entry.exception;
        }
     }
}

The exception will be handled in the call back function or in the asynchronous method if an exception handler is provided. This is how it works without a debugger attached.

When you run it in VS.NET, the debugger seems checking only the presence of the exception handler in the asynchronous method. If there is no such handler, the debugger would think the exception is not handled and pop up an error message notifying you of this.

Suggestion:

The application should work as expected when you run it stand alone. If the error message is annoying in debugging for you, you can disable it by unchecking “User unhandled” for “Common Language Runtime Exceptions”in the Exception dialog box (Debug|Exceptions or press CTRL+ATL+E). Or you can add try/catch in the asynchronous method. In the latter case, the exception is set to null and won’t be re-thrown in EndInvoke().

makerofthings7
  • 60,103
  • 53
  • 215
  • 448
  • thanks! Can you post a link to the case #? I couldn't find a search tool on Microsoft Connect. I'm a little confused by his answer, because my whole issue is that I **do** have "user unhandled" unchecked, yet the exception popup still appears. – Dave May 31 '11 at 13:09
  • The case number is visible to MSFT employees, MVP's, and some Partners. It's not on connect. I solved my problem by implementing a dummy do nothing `try..catch..throw` in the body of my async method and all is fine. – makerofthings7 May 31 '11 at 13:37
0

I'm having this same problem, so I'll post this possible workaround for posterity's sake:

In your code that throws an exception into the .NET code (HardwareTestThread() in the example above,) catch the exception that's being thrown and wrap it in some esoteric .NET exception type for which you can disable the "user-unhandled" option in the Debug>Exceptions dialog. For my case, I needed to allow an IOException to propagate through some .NET code back to my code, so I just caught the IOException and wrapped in an AppDomainUnloadedException before letting it propagate through the .NET code back to my catch block. I chose AppDomainUnloadedException because user-unhandled is unchecked for it by default and it's in the System.dll assembly, so it was already being imported in my project, though any exception should work, so long as you disable the "user-unhandled" option for it and you don't care that the debugger won't break on that type of exception in the future.

Here's my code that wraps the IOException I was needing to propagate:

public override int Read(byte[] buffer, int offset, int count)
{
    try { return innerStream.Read(buffer, offset, count); }
    catch (IOException ex) { throw new AppDomainUnloadedException("Exception from innerStream: " + ex.Message, ex); }
}

And here's my code where I'm catching it on the other side of the .NET code it needed to propagate through:

try { bytesRead = sslStream.Read(buffer, offset, count); }
catch (Exception ex) { /* ex handled here. */ }
reirab
  • 1,535
  • 14
  • 32