我正在使用PCLStorage库来访问多个平台上的文件。
该库仅提供异步方法。我在lock
块中使用这些方法,以便它们可以同步运行。我正在使用.Result
等待调用结果。我试图在这个锁中捕获异常,但因为AggregateException
被抛出,它将不会到达我的catch块。
lock (this)
{
try
{
IFile file = folder.GetFileAsync (FileName).Result;
}
catch (FileNotFoundException)
{
//won't be catched
}
}
如何在lock
内找到原始异常?
答案 0 :(得分:3)
要在等待Task
完成时阻止当前线程,并获取解包的Task
异常(如果有),您可以执行以下操作:
try
{
var file = folder.GetFileAsync(FileName).GetAwaiter().GetResult();
}
catch (FileNotFoundException)
{
// Will be catched :)
}
如果您阻止.Result
属性,则需要捕获AggregateExcetpion
并检查其内部异常。
要获得更多相关信息,我可以在A Tour of Task
上推荐Stephen Cleary的博客系列。在Part 6: Results,他写道:
<强>
Result
强> 与Wait
一样,Result
将同步阻止调用线程,直到任务完成。 (...)此外,Result
将换行AggregateException
内的任何任务异常。这通常只是 使错误处理变得复杂。
GetAwaiter().GetResult()
{4.5}中的GetAwaiter
成员已添加到Task
和Task<T>
,并且可以作为扩展方法使用 .NET 4.0使用Microsoft.Bcl.Async
NuGet包。 (...)在 一般来说,我尽量避免同步阻止 异步任务。但是,我有几种情况 确实违反了该准则。在那些罕见的情况下,我的首选 方法是GetAwaiter().GetResult()
,因为它保留了任务 异常,而不是将它们包装在AggregateException
。
答案 1 :(得分:1)
如何在锁定内部时捕获原始异常?
你没有。您必须捕获聚合异常,解包它,并查看内部异常是什么。如果这是你无法处理的异常,那么你总是可以重新抛出它。
我在
lock
块中使用这些方法,因此它们可以异步运行
使用lock
不会使其异步。最重要的是,你同步阻止它,所以你甚至没有这样做。这句话完全没有意义。