简体   繁体   English

任务中的异常未导致应用程序崩溃

[英]Exception in a task not causing the application to crash

I am new to Task Parallel Library. 我是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. 如果我没看错,则Task使用后台线程,因此异常应传播到主线程并像正常的后台线程一样崩溃。

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 . 您应该Wait()您的Task If a task has a result one can access Result property that calls Wait() . 如果一项任务有结果,则可以访问调用Wait() Result属性。 Note that an exception will be AggregateException and original exceptions will be in its InnerExceptions collection. 请注意,异常将为AggregateException ,原始异常将在其InnerExceptions集合中。

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. await任务时,您说您想知道任务的结果。 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 看看这个: https : //docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/await#exceptions

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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