4

I have a Windows Forms application with a single Editor class (that inherits from Form).

public partial class Editor : Form
{
    public Editor()
    {
        InitializeComponent();

        Load += Editor_Load;
    }

    private void Editor_Load(object sender, EventArgs e)
    {
        cmbConnections.DataSource = ConnectionManager.Connections;
        cmbConnections.Visible = false;
    }

}

Other than designer-generated code, this is the only code for the form (that contains only a single Combo Box (cmbConnections).

The ConnectionManager class is a static class with a static constructor. It's constructor does some initialization and then tests for some critical condition. If the condition is met, the constructor throws an exception. However, this exception does not break in the debugging mode in Visual Studio 2010. To test this, I've put only throw new Exception() in the ConnectionManager's static constructor. The ConnectionManager is used and therefor initialized (for the first time) in the Editor_Load event handler. Static constructor is called and exception thrown (visible only in output window). The rest of the Editor_Load event handler (cmbConnections.Visible = false;) is not executed, just as expected.

But what I don't understand is why did my VS2010 swallow the exception? It did not break the debug. It is not enclosed in any try/catch block. It continued with program execution with the main window. It almost seems as if the Editor_Load was executed on another thread.

I can see the messages in output window:

A first chance exception of type 'System.InvalidOperationException' occurred in Editor.exe

A first chance exception of type 'System.TypeInitializationException' occurred in Editor.exe

but the execution simply did not break in debug mode.

Here are some of my options that I believe may influence this behavior:

Project Properties->Build->General-> Optimize code is UNCHECKED.

Tools->Options->Debugging->General-> Enable Just My Code is CHECKED.

In exception settings, the checkbox for the "user-unhandled" is CHECKED.

Am I missing something? Is this behavior normal? I thought that VS2010 will throw on ANY unhandled exception. And here this one is unhandled and still does not break.

Community
  • 1
  • 1
Kornelije Petak
  • 9,412
  • 15
  • 68
  • 96
  • 2
    You forgot to mention that you've got a 64-bit operating system. Crappy problem, easy fix: Project + Properties, Build tab, change Platform target from x86 to AnyCPU. – Hans Passant Feb 10 '12 at 00:32
  • I have not yet been able to check this on my x64 system (on which I was developing yesterday). However, I've tried the same solution on x86 system and it did actually break VS2010. So I guess your comment may be correct. I'd recommend you post this as an answer. Cause all other answers contain information not really relevant to the question, but merely explain how VS2010 exception handling work. My question was about why VS2010 behaves OUT OF it's own standards - and I guess you answered - it's some kind of a bug on x64 system. I will test this on x64 as soon as I can to confirm. – Kornelije Petak Feb 10 '12 at 09:48
  • possible duplicate of [VS2010 does not show unhandled exception message in a 64-bit WinForms Application](http://stackoverflow.com/questions/4933958/vs2010-does-not-show-unhandled-exception-message-in-a-64-bit-winforms-applicatio) – Hans Passant Feb 10 '12 at 12:36
  • While the "duplicate"'s question deals with the form constructor, my question deals with static constructors. The solution may be the same, but the questions are not. However, now I wonder what would be the pattern here - which exceptions does it swallow, and which it does not. That's a strange bug indeed. – Kornelije Petak Feb 10 '12 at 13:30

1 Answers1

1

I think it is by design that you need to enable Managed (.NET) Exceptions 'Thrown' in the Exceptions Dialog (Ctrl-Alt-E).1

To avoid many spurious (handled) exceptions, I usually try to get close to the point where the initializer will be run and then check that checkbox just before continueing.

Also, if there are loader exceptions, be sure to check the nested inner exceptions or loader information in the exception: the exception itself is usually not that informative. I have frequently had to dig through 2 or more layers of wrapping exceptions in order to get at the actual error.


1 I can only guess as to why that is; My feeling is that the static type initializers are not considered to be run deterministically (many things could trigger it and the order is often undefined; it is just guaranteed that a type's static constructor will have been run before it is used, but it can be used at almost any point in the code, without you knowing or explicitely triggering that).

Therefore, it would be hard for the runtime to establish whether it was 'handled by user code' (no user should expect to handle it, because it doesn't know - deterministically - when the initializer will run).

However, this is conjecture on my part.

Richard Banks
  • 12,456
  • 3
  • 46
  • 62
sehe
  • 374,641
  • 47
  • 450
  • 633