问题
short version, this method:
public override async void MethodWithException()
{
throw new Exception("any EXCEPTION type and format will be skipped by outer try-catch block");
}
is not caught by this block ("catch" is skipped):
try
{
realClassFromAbstractObject.MethodWithException();
Console.WriteLine("Output in the console – NOT POSSIBLE but true!");
}
catch (Exception exception)
{
//Nothing caught!
Console.WriteLine("2. Nothing in console, skipped exception! " + exception); //--- Notihng in the output
}
This is super strange behaviour.
Full: please take a look at the short demo, that I made:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("1. Program starts"); //+++ Yes, in the console
RealClassFromAbstract realClassFromAbstractObject = new RealClassFromAbstract();
Task.Factory.StartNew(() =>
{
try
{
//Next method should to throw an exception! But nothing!
realClassFromAbstractObject.MethodWithException();
Console.WriteLine("In the console too – NOT POSSIBLE but true!"); //+++ Yes, in the console
}
catch (Exception exception)
{
//Nothing caught!
Console.WriteLine("2. Nothing in console, skipped exception! " + exception); //--- Notihng in the output
}
}).ConfigureAwait(false);
Console.WriteLine("3. Program ends"); //+++ Yes, in the console
Console.ReadKey();
}
}
abstract class AbstractClass
{
public abstract void MethodWithException();
}
class RealClassFromAbstract : AbstractClass
{
public override async void MethodWithException()
{
throw new Exception("any EXCEPTION type and format will be skipped by outer try-catch block");
throw new ArgumentException();
throw new DivideByZeroException();
//Anythig else, await....
}
}
This is simplified example from real project. If you have any suggestion how to make catch block to work again, as usual, please let me know. Thanks! This is first time, when catch block have such a strange behaviour.
Download: console application demo project – https://www.dropbox.com/s/x8ta7dndbijxbvq/ConsoleAppExceptionTryCatchProblem.zip?dl=1 (please run without a debugging, so that you can immediately see the result)
回答1:
Thank everyone for the answers, especially @MickyD for great link with article
Answer: Avoid Async Void, explanations - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
If anybody will have same problem, fixed code, all changes with comments:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("1. Program starts"); //+++ Yes, in the console
RealClassFromAbstract realClassFromAbstractObject = new RealClassFromAbstract();
Task.Factory.StartNew(async () =>//CHANGE 1/5: async lambda
{
try
{
//CHANGE 2/5: await
await realClassFromAbstractObject.MethodWithException();
Console.WriteLine("Nothing in the console, that's correct"); //--- Notihng in the console
}
catch (Exception exception)
{
Console.WriteLine("2. Nice, exception! " + exception); //+++ Yes, in the console!
}
}).ConfigureAwait(false);
Console.WriteLine("3. Program ends"); //+++ Yes, in the console
Console.ReadKey();
}
}
abstract class AbstractClass
{
//CHANGE 3/5: returned type is Task
public abstract Task MethodWithException();
}
class RealClassFromAbstract : AbstractClass
{
//CHANGE 4/5: returned type is Task according to the abstact class
public override async Task MethodWithException()
{
throw new Exception("This exception would be caught by outer try-catch block");
//Anythig else, await....
await Task.Delay(3);
//CHANGE 5/5: await or:
return;//or "Task.CompletedTask" in .NET >=4.6 if no awaits or Task.FromResult() in .NET <4.6
}
}
In the real project, that part of the code, was really old. First version was synchronous -> second was working with together with BackgroundWorker -> after that straight Threads and only after ->– Task, but before async/await. At the last stage, errors were made during the development.
Most interesting that everything was working for at least two years without problems. I got strange application level exceptions only last week while testing. Thanks you very much for all answers!
来源:https://stackoverflow.com/questions/45131200/c-sharp-trycatchexception-ex-do-not-caught-any-exception