我想知道如何让此代码落入catch
的{{1}}中?
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);
}
}
?
通过Task.FromException
吗?
答案 0 :(得分:2)
我的建议是将您的PassThrough
方法更改为采用Func<Task<bool>>
而不是Task<bool>
。这样,您可以捕获由Test
方法的同步部分及其启动的异步任务引起的异常。另一个优势是,异步方法(使用async
和await
定义的方法可以直接转换为Func<Task>
或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);
}
}
答案 1 :(得分:1)
添加到Douglas的答案中。
仅当您能够对异常进行有意义的处理并且可以在该级别进行管理时,才捕获异常。
Task.FromException
基本上只是将异常放在通常要返回的任务上。但是,在这种情况下,异步等待模式已经为您完成了此操作。即,如果您只是让它失败,那么无论如何都会将异常放置在任务上,因此您的代码似乎没有真正的理由来捕获任何东西。
您必须考虑捕获异常的唯一相关位置是在async void
中,因为它们不会被观察到,并且在引发异常时会引起问题
答案 2 :(得分:0)
在下面的行中,您正在等待PassThrough
,而不是Test
。
await PassThrough(Test());
如果需要,您可以同时等待两者:
await PassThrough(await Test()); // also need to change the signature of PassThrough from Task<bool> to bool.
...但是在两种情况下,都将首先调用Test
。并且由于它引发了异常,因此PassThrough
将永远不会被调用。这就是您看不到“通行卡住” 消息的原因。执行过程永远不会输入此方法。