简体   繁体   中英

Exception in a task not causing the application to crash

I am new to Task Parallel Library. I know that exceptions in foreground and background threads work in the same way i,e they propagate to the main thread and crash the application(if not handled). But, I am seeing a different behaviour while using tasks. When am exception occurs in a Task it just ends its execution without crashing the application or other tasks. If I am not wrong, a Task uses a background thread so the exception should be propagate to the Main thread and crash like a normal Background thread.

public static void Foo()
{
  throw new Exception("Blahh");
}
static void Main()
{
   Task t = Task.Run(()=>Foo());
   Thread.Sleep(500);
   Console.WriteLine("Main");
}

You should Wait() your Task . If a task has a result one can access Result property that calls Wait() . Note that an exception will be AggregateException and original exceptions will be in its InnerExceptions collection.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Program
    {
        static void Main()
        {
            Example1();
            Example2();
            Thread.Sleep(500);
            Console.WriteLine("Main");
        }

        public static void Example1()
        {
            try
            {
                Console.WriteLine("Example1");
                Task t = Task.Run(() => Foo());
                t.Wait();
            }
            catch (AggregateException e)
            {
                foreach (var ex in e.InnerExceptions)
                    Console.WriteLine(ex.Message);
            }
        }

        public static void Example2()
        {
            try
            {
                Console.WriteLine("Example2");
                Task<string> t = Task.Run(() => { Foo(); return "Task result"; });
                string result = t.Result;
                Console.Write(result);
            }
            catch (AggregateException e)
            {
                foreach (var ex in e.InnerExceptions)
                    Console.WriteLine(ex.Message);
            }
        }

        public static void Foo()
        {
            throw new Exception("Blahh Exception");
        }
    }
}

You should change the code to

public static void Foo()
{
  throw new Exception("Blahh");
}
static async Task Main()
{
   Task t = Task.Run(()=>Foo());
   Thread.Sleep(500);

   await t;

   Console.WriteLine("Main");
}

What you do now is you run a fire-and-forget task. So you actually say, I don't care about the result (even the exception).

When you await a task you say you want to know the result of the task. In this case you do it to know if the task completed successfully (or threw an exception).

Take a look at this: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/await#exceptions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM