Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task and exception silence

Why exceptions thrown within a task are silent exception and you never know if a certain exception has been thrown

try
{

 Task task = new Task(
  () => {
          throw null;
        }
        );
  task.Start();
 }
 catch
 {
  Console.WriteLine("Exception");
 }  

the program run successfully in a complete silence! where the behavior of threads is different

try
{

 Thread thread = new Thread(
  () => {
          throw null;
        }
        );
  thread .Start();
 }
 catch
 {
  Console.WriteLine("Exception");
 }

a null pointer exception will be thrown in this case. What is the difference?

like image 827
Sleiman Jneidi Avatar asked Jan 10 '12 12:01

Sleiman Jneidi


People also ask

What is a silent exception?

You can also define "silent" exceptions that do not, by default, cause the application to show the error message. Silent exceptions are useful when you don't intend to report an exception to the user, but you want to abort an operation.

What happens when a task throws an exception?

If Bar throws an exception, it will be thrown right at the point where you call it. However, if the Task that Bar returns wraps an exception, what happens depends on your version of . NET runtime - for .

How do you handle exceptions in tasks?

Exceptions are propagated when you use one of the static or instance Task. Wait methods, and you handle them by enclosing the call in a try / catch statement. If a task is the parent of attached child tasks, or if you are waiting on multiple tasks, multiple exceptions could be thrown.


1 Answers

The behaviour of that scenario depends on what framework you have; in 4.0, you actually need to be careful - if you don't handle TaskScheduler.UnobservedTaskException, it will error later when it gets collected/finalized, and will kill your process.

TaskScheduler.UnobservedTaskException += (sender, args) =>
{
    Trace.WriteLine(args.Exception.Message); // somebody forgot to check!
    args.SetObserved();
};

This changes in 4.5, IIRC.

To check the outcome of a Task that might fail, you could register a continuation - i.e. call ContinueWith and check the result's exception. Alternatively, accessing the .Result of the task (which would also do an implicit Wait()) will re-surface the exception that happened. It is good to observe the result of a task, as that clears the finalization flag, meaning it can be collected more cheaply.

like image 56
Marc Gravell Avatar answered Sep 19 '22 17:09

Marc Gravell