Windows swallows exceptions
-
I knew that exceptions in the
Load
orShown
event of aForm
get swallowed on 64bit systems (see e.g. https://connect.microsoft.com/VisualStudio/feedback/details/357311[^]). But this was not such an event. The autosave procedure of our application receives its start signal from aSystem.Timers.Timer
. The log file entries showed that theTimer_Elapsed
handler was called. But strangely, not all of it... But nowhere an exception could be found in the log files, autosave simply did not work. A newer version of a ThirdParty control fails at a property get when not run in the UI thread - that's where the execution of the Elapsed handler suddenly stopped. But actually that's nothing new at all, you can read in the MSDN[^]Quote:
In the .NET Framework version 2.0 and earlier, the Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event. This behavior is subject to change in future releases of the .NET Framework.
Still true with .Net 4. Now I know that too.
-
I knew that exceptions in the
Load
orShown
event of aForm
get swallowed on 64bit systems (see e.g. https://connect.microsoft.com/VisualStudio/feedback/details/357311[^]). But this was not such an event. The autosave procedure of our application receives its start signal from aSystem.Timers.Timer
. The log file entries showed that theTimer_Elapsed
handler was called. But strangely, not all of it... But nowhere an exception could be found in the log files, autosave simply did not work. A newer version of a ThirdParty control fails at a property get when not run in the UI thread - that's where the execution of the Elapsed handler suddenly stopped. But actually that's nothing new at all, you can read in the MSDN[^]Quote:
In the .NET Framework version 2.0 and earlier, the Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event. This behavior is subject to change in future releases of the .NET Framework.
Still true with .Net 4. Now I know that too.
System.Timers.Timer runs in its own Thread. If you don't catch the exceptions in there (e.g. You don't have a try catch around everything in the Elapsed Event) the exception is lost.
-
System.Timers.Timer runs in its own Thread. If you don't catch the exceptions in there (e.g. You don't have a try catch around everything in the Elapsed Event) the exception is lost.
-
And if it did not swallow the exception, your entire application would go down with a unhandled exception. I guess the designers decided that it was better to not let the application die due to a simple timed event (that would likely execute again)
There are two ways to crash your application: - The exception occurred on the main thread (that is the same as where the
main
function is called) - Corrupted State Exceptions that you usually just can't handle (e.g. AccessViolationException, StackOverflowException (if thrown by the OS), etc.) and the application just isn't in a state where it could continue (Yeah, I know, you CAN catch an AccessViolationException, but it's generally not encouraged) I don't see any reason why an entire application should go boom because one single thread messed something up ;) -
There are two ways to crash your application: - The exception occurred on the main thread (that is the same as where the
main
function is called) - Corrupted State Exceptions that you usually just can't handle (e.g. AccessViolationException, StackOverflowException (if thrown by the OS), etc.) and the application just isn't in a state where it could continue (Yeah, I know, you CAN catch an AccessViolationException, but it's generally not encouraged) I don't see any reason why an entire application should go boom because one single thread messed something up ;)Nicholas Marty wrote:
I don't see any reason why an entire application should go boom because one single thread messed something up ;)
- So that you know it did! Trying to save people from themselves is not generally a worthwhile endeavor.
This space intentionally left blank.
-
And if it did not swallow the exception, your entire application would go down with a unhandled exception. I guess the designers decided that it was better to not let the application die due to a simple timed event (that would likely execute again)
Sentenryu wrote:
I guess the designers decided that it was better to not let the application die due to a simple timed event (that would likely execute again)
Let the developer decide what to do; it's not your job.
This space intentionally left blank.
-
There are two ways to crash your application: - The exception occurred on the main thread (that is the same as where the
main
function is called) - Corrupted State Exceptions that you usually just can't handle (e.g. AccessViolationException, StackOverflowException (if thrown by the OS), etc.) and the application just isn't in a state where it could continue (Yeah, I know, you CAN catch an AccessViolationException, but it's generally not encouraged) I don't see any reason why an entire application should go boom because one single thread messed something up ;)run this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {new Thread(\_ => { throw new ArgumentException(); }).Start(); for (int i = 0; i < 1000; i++) { Console.WriteLine("Wasting time..."); } Console.ReadKey(); } }
}
The application crashes with an unhandled exception. ANY unhandled exception on ANY thread crashes the app. I Learned this from C# 5.0 in a nutshell from john albahari, here's an excerpt:
Quote:
AppDomain.CurrentDomain.UnhandledException fires on any unhandled exception on any thread, but since CLR 2.0, the CLR forces application shutdown after your event handler completes.
Also, for anyone reading this, I strongly recomend that book.
-
Sentenryu wrote:
I guess the designers decided that it was better to not let the application die due to a simple timed event (that would likely execute again)
Let the developer decide what to do; it's not your job.
This space intentionally left blank.
-
<mumbling>Self-righteous b-tards...</mumbling>
This space intentionally left blank.
-
run this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {new Thread(\_ => { throw new ArgumentException(); }).Start(); for (int i = 0; i < 1000; i++) { Console.WriteLine("Wasting time..."); } Console.ReadKey(); } }
}
The application crashes with an unhandled exception. ANY unhandled exception on ANY thread crashes the app. I Learned this from C# 5.0 in a nutshell from john albahari, here's an excerpt:
Quote:
AppDomain.CurrentDomain.UnhandledException fires on any unhandled exception on any thread, but since CLR 2.0, the CLR forces application shutdown after your event handler completes.
Also, for anyone reading this, I strongly recomend that book.
As well it should; what's your point?
This space intentionally left blank.
-
As well it should; what's your point?
This space intentionally left blank.
I was just giving my 2 cents on why that design decision might have been made, without getting into the merit of saying if it's the right way™ or not. I do defend the crash on this situation, as there's no way to know if the thread ended on a valid state or not. I interpreted Nicholas Marty's answer as saying that those are the only ways an application might terminate due to an unhandled exception, and felt the necessity to point out that an unhandled exception on any thread would terminate the application, and not just on the main thread, as was implied. It's also worth noting that if the unhandled exception is on another app domain, you can just handle the AppDomain.CurrentDomain.UnhandledException trashing the offending app domain, then continuing to run normally.
-
run this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {new Thread(\_ => { throw new ArgumentException(); }).Start(); for (int i = 0; i < 1000; i++) { Console.WriteLine("Wasting time..."); } Console.ReadKey(); } }
}
The application crashes with an unhandled exception. ANY unhandled exception on ANY thread crashes the app. I Learned this from C# 5.0 in a nutshell from john albahari, here's an excerpt:
Quote:
AppDomain.CurrentDomain.UnhandledException fires on any unhandled exception on any thread, but since CLR 2.0, the CLR forces application shutdown after your event handler completes.
Also, for anyone reading this, I strongly recomend that book.
Hi Sentenryu, Run this:
using System;
using System.Timers;namespace TimerTest
{
static class Program
{
[STAThread]
static void Main()
{
System.Timers.Timer timer = new Timer();
timer.Elapsed += (object sender, ElapsedEventArgs e) => { throw new NotImplementedException(); };
timer.Start();Console.ReadKey(); } }
}
I think OP's point was, that in some circumstances your "rule" (from the very good book) doesn't apply. If you don't know the documented behaviour in this case, you may scratch your head like OP did... :wtf:
-
Hi Sentenryu, Run this:
using System;
using System.Timers;namespace TimerTest
{
static class Program
{
[STAThread]
static void Main()
{
System.Timers.Timer timer = new Timer();
timer.Elapsed += (object sender, ElapsedEventArgs e) => { throw new NotImplementedException(); };
timer.Start();Console.ReadKey(); } }
}
I think OP's point was, that in some circumstances your "rule" (from the very good book) doesn't apply. If you don't know the documented behaviour in this case, you may scratch your head like OP did... :wtf:
you didn't read the full thread... the message before the one you replied states that the timer class catches the exceptions, and that is documented:
Quote:
In the .NET Framework version 2.0 and earlier, the Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event. This behavior is subject to change in future releases of the .NET Framework.
MSDN link: http://msdn.microsoft.com/pt-BR/library/system.timers.timer%28v=vs.110%29.aspx[^]
-
you didn't read the full thread... the message before the one you replied states that the timer class catches the exceptions, and that is documented:
Quote:
In the .NET Framework version 2.0 and earlier, the Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event. This behavior is subject to change in future releases of the .NET Framework.
MSDN link: http://msdn.microsoft.com/pt-BR/library/system.timers.timer%28v=vs.110%29.aspx[^]
Ah you are right - sorry for overseeing your first post - So Forget my post. :-O But at least I knew about this and that it's documented - thank you anyway for clarification