Reputation: 7128
I am trying to catch exceptions within a Task
I have created but they never "bubble up" to where the Task
is ran from, they are always caught by Visual Studio as runtime errors.
Here is a SSCCE I have created to show the issue
using System;
using System.Threading.Tasks;
namespace ConsoleApplicationSandbox
{
class Program
{
static void Main(string[] args)
{
CreateTheIssue();
Console.ReadLine();
}
public static async void CreateTheIssue()
{
try
{
int val = await ExceptionThrowerClass.DoSomething();
}
catch(Exception ex)
{
Console.Out.WriteLine("Exception of type " + ex.GetType() + " caught, message: " + ex.Message);
}
}
}
public static class ExceptionThrowerClass
{
public static Task<int> DoSomething()
{
return Task.Run(() =>
{
throw new FooException("How exceptional!");
return 1;
});
}
}
public class FooException : Exception
{
public FooException() : base () { }
public FooException(String message) : base(message) { }
public FooException(String message, Exception inner) : base (message, inner) { }
}
}
Visual Studio notifies me when I throw FooExcepion
in DoSomething
that the exception is not being caught. From this SO answer and this MSDN page I thought that the exceptions would just "bubble up" to myTask.Wait()
and subsequently be caught. Though this does not seem to be that case.
The project settings for this SCCEE are targeting .NET 4.5.2 and I am using Visual Studio 2015. Is it that my targeted .NET framework cannot catch exceptions in this manner? How can I catch FooException
in the try/catch
block within Main
?
EDIT: I have altered the SSCCE to use the async
/await
pattern instead of Task.Wait
.
Upvotes: 1
Views: 401
Reputation: 127543
Hit the Continue
button, you will see that the exception does get caught in the outer try/catch. Because the exception crossed in to the innards of Task
the exception was considered "User Unhanded", however Task
handels it for you by putting the task in to the Faulted
state. This will a exception to be re-raised when you await
or .Wait()
the task.
Using your original method before your edit would need to do
try
{
myTask.Wait();
}
catch(AggregateException ex)
{
var innerException = ex.InnerException;
Console.Out.WriteLine("Exception of type " + innerException .GetType() + " caught, message: " + innerException.Message);
}
Because the Task will wrap the exceptions up in to a AggregateException
, when you use await
it unwraps the exception for you.
Upvotes: 2