I'm wondering how I can let this code fall in the catch
of PassThrough
?
using System;
using System.Threading.Tasks;
public class Program
{
public static async Task Main(string[] args)
{
try
{
await PassThrough(Test());
} catch (Exception) {
Console.WriteLine("caught at invocation");
}
Console.ReadLine();
}
public static async Task PassThrough(Task<bool> test)
{
try
{
var result = await test.ConfigureAwait(false);
// still need to do something with result here...
}
catch
{
Console.WriteLine("never caught... :(");
}
}
/// external code!
public static Task<bool> Test()
{
throw new Exception("something bad");
// do other async stuff here
// ...
return Task.FromResult(true);
}
}
The external code should return handle the error path and return Task.FromException
?
Pass a Func<Task<bool>>
?
My recommendation would be to change your PassThrough
method to take a Func<Task<bool>>
instead of a Task<bool>
. This way, you can capture exceptions arising both from the synchronous part of your Test
method, as well as the asynchronous task it launches. An added advantage is that asynchronous methods (defined using async
and await
) can be directly cast to Func<Task>
or Func<Task<TResult>>
.
using System;
using System.Threading.Tasks;
public class Program
{
public static async Task Main()
{
try
{
await PassThrough(Test);
// Note that we are now passing in a function delegate for Test,
// equivalent to () => Test(), not its result.
}
catch (Exception)
{
Console.WriteLine("caught at invocation");
}
Console.ReadLine();
}
public static async Task PassThrough(Func<Task<bool>> test)
{
try
{
var task = test(); // exception thrown here
var result = await task.ConfigureAwait(false);
// still need to do something with result here...
}
catch
{
Console.WriteLine("caught in PassThrough");
}
}
/// external code!
public static Task<bool> Test()
{
throw new Exception("something bad");
// do other async stuff here
// ...
return Task.FromResult(true);
}
}
Adding to Douglas 's answer.
Only catch exceptions if you are able to do something meaningful with them and you can manage them at that level.
Task.FromException
basically just places the exception on a task which you would usually return. However, in this case the Async Await Pattern already does this for you. ie If you just let it fail, the exception will get placed on the task anyway, so there seems no real reason from your code to catch anything.
The only pertinent place you have to think about catching exceptions is in async void
as they run unobserved and can cause issues when an exception is thrown
In the following line you are awaiting the PassThrough
, not the Test
.
await PassThrough(Test());
You could await both if you wanted:
await PassThrough(await Test()); // also need to change the signature of PassThrough from Task<bool> to bool.
...but in both cases the Test
will be invoked first. And since it throws an exception, the PassThrough
will never be invoked. This is the reason you don't see the "caught in PassThrough" message. The execution never enters this method.
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.