4

I tried using

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx#Y399

but when I do this

throw new ArgumentNullException("playlist is empty");

I get nothing. I bet I'm missing something very obvious.

here is my code.

using System;
using System.Security.Permissions;
using System.Windows.Forms;
using System.Threading;

namespace MediaPlayer.NET
{
    internal static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
        private static void Main()
        {
            // Add the event handler for handling UI thread exceptions to the event.
            Application.ThreadException += new ThreadExceptionEventHandler(UIThreadException);

            // Set the unhandled exception mode to force all Windows Forms errors to go through
            // our handler.
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

            // Add the event handler for handling non-UI thread exceptions to the event. 
            AppDomain.CurrentDomain.UnhandledException +=
                new UnhandledExceptionEventHandler(UnhandledException);

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MediaPlayerForm());
        }

        private static void UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show("UnhandledException!!!!");
        }

        private static void UIThreadException(object sender, ThreadExceptionEventArgs t)
        {
            MessageBox.Show("UIThreadException!!!!",
                            "UIThreadException!!!!", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
            Application.Exit();
        }
    }
}
IAdapter
  • 62,595
  • 73
  • 179
  • 242
  • the line `[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]` is necessary for handling exceptions that are generating on threads? – Amogh May 26 '16 at 11:36

2 Answers2

12

Your code works fine, there are not a lot of possible failure modes I can think of. Except one, there's a problem in the interaction between the debugger and Windows SEH when you debug 32-bit code on a 64-bit operating system prior to Windows 8. This can cause exceptions to be swallowed without any diagnostic when they occur in the form's Load event or OnLoad() method override. Check the linked post for workarounds, the simplest one is Project + Properties, Build tab, Platform Target = AnyCPU, untick "Prefer 32-bit" if you see it.

In general, you are doing the appropriate thing by not letting the default exception handling of an Application.ThreadException display the dialog. But keep it simple, do it like this:

#if (!DEBUG)
      Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
#endif

Now you never have to worry about a ThreadException anymore, all exceptions trigger the AppDomain.UnhandledException event handler. And the #if around the code still lets you debug an unhandled exception, the debugger will automatically stop when the exception is raised.

Add this to the UnhandledException method to prevent the Windows crash notification from showing up:

        Environment.Exit(1);
Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • the line `[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]` is necessary for handling exceptions that are generating on threads? – Amogh May 26 '16 at 11:36
  • Click the Ask Question button. Don't forget to mention that you are using some kind of code analyzer, sounds like you do. – Hans Passant May 26 '16 at 11:41
  • @HansPassant You write `#ifndef` in the code snippet and `#ifdef` in the text. It should be `#if` in both places, shouldn't it? i.e. throw in Debug, default (catch) in Release. – jacob1123 Jul 13 '16 at 16:10
2

You haven't show where you're throwing the ArgumentNullException. My guess is that it's either within the constructor of MediaPlayerForm (which means it's before the message loop has started) or it's in a different thread. Application.ThreadException only handles exceptions caught on Windows Forms threads running message loops.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194