当访问异常时,过滤器异常处理程序中的代码抛出NullReferenceException

10
当我使用.NET Native编译器编译UWP应用程序并开启代码优化(通常是发布模式)时,在catch块中尝试访问实际异常时,会出现NullReferenceException。
代码示例:
try
{
    throw new ArgumentNullException("Param");
}
catch (ArgumentNullException ex) when (ex.ParamName == "Param")
{
    ErrorBlock.Text = ex.ParamName; // ErrorBlock is a TextBlock in the xaml
}
catch (Exception)
{
}

当我访问ex时,它进入了正确的catch块,并抛出NullReferenceException。只有在同时开启 .Net Native 和代码优化时才会失败。

是什么导致了这个问题?


1
@Pan,为什么要删除这些标签?它们似乎与此构建模式有关,因此可能是 .NET Native 编译器的问题。 - Patrick Hofman
因为它们是不相关的。exc.Message 是空的。这是一个普通的 NulLReferenceException。OP 调用了只接受参数名称的构造函数。 - Panagiotis Kanavos
3
不,它不是... 该消息已被默认。请自行尝试此代码。 - Patrick Hofman
2
是的,这不是一个普通的 NRE(NullReferenceException)... 异常可以在它上面的那一行被很好地解除引用。 - FUR10N
异常在它上面的那一行可以很好地被取消引用,是的也不完全是,异常过滤器并不那么简单。 - CodeCaster
2个回答

5

我不确定为什么出现问题(已经调试了一段时间),但缺乏await使我很好奇。

如果你使用await来调用ShowAsync方法,代码就可以正常运行(显然,如果你还没有将该方法设置为async,则需要这样做):

await new MessageDialog("Argument null exception: " + argEx.Message).ShowAsync();

没有使用await的代码块失败了。不确定这是否是一个错误,或者您是否应该修复它...


嗯,这对我也起作用了!我没有意识到它与async/await有关。我在实际代码中发现,这并不是要等待特定的结果(它们都在ICommands中,所以它们将是async void)。我认为你不应该被要求无论如何都去等待它,对吧? - FUR10N
是的,每个 async 都应该被 await - Patrick Hofman
这是一个长时间运行的任务,我不需要安排继续执行。我想要的是“发射并忘记”的行为。等待它并不是一个真正的选择。 - FUR10N
我进行了更多的测试,这似乎与异步/等待没有关系。 - FUR10N
你能告诉我们你发现了什么吗? - Patrick Hofman
我已经更新了代码。不再使用MessageDialog,而是在页面上添加了一个TextBlock并尝试仅更新它。我仍然遇到了NRE,但奇怪的是我可以在调试器中访问异常。 - FUR10N

2
我在.NET Native运行时和编译器团队工作。
这是我们编译器内部的一个bug。您可以将每个异常处理区域(try,catch,finally,when)视为小函数或“funclet”。当为“when”(也称为过滤块)设置堆栈时,我们会丢失异常对象的跟踪。这个bug已经在Windows Tools 1.3中得到了修正,如果没有重大挫折,应该会在另外一两周内发布。对于安装了VS 2015 Update 2的用户,它将显示为更新。
如果您有其他问题,请告诉我。

谢谢@Matt!我在以下三种情况下看到了略微不同的行为:非异步、异步但未等待和异步+等待。当更新出来时,我会尝试这三种情况。 - FUR10N
太好了。请告诉我们进展如何。我们很乐意听取来自dotnetnative@microsoft.com的反馈。 - MattWhilden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接