C# Catch不执行其代码
我正在为WindowsPhone8.1(Silverlight)开发C#应用程序。最近我遇到了与应用程序睡着和故事板相关的问题 结构如下:C# Catch不执行其代码,c#,silverlight,windows-phone-8.1,C#,Silverlight,Windows Phone 8.1,我正在为WindowsPhone8.1(Silverlight)开发C#应用程序。最近我遇到了与应用程序睡着和故事板相关的问题 结构如下: class X : DependencyObject { public static readonly DependencyProperty vProperty = DependencyProperty.Register("v", typeof(double), typeof(X), new PropertyMetadata(0.0)
class X : DependencyObject
{
public static readonly DependencyProperty vProperty =
DependencyProperty.Register("v", typeof(double), typeof(X), new PropertyMetadata(0.0));
public double v
{
get
{
return (double)GetValue(vProperty);
}
set
{
SetValue(vProperty, value);
}
}
private Storyboard _storyboard;
void Prepare()
{
_storyboard = new Storyboard();
var animation= new DoubleAnimation
{
From = 0,
To = 1,
BeginTime = 0,
Duration = 0,
};
_storyboard.Children.Add(animation);
Storyboard.SetTarget(animation, this);
Storyboard.SetTargetProperty(animation, vProperty);
}
void Go()
{
_storyboard.Begin();
}
}
如果应用程序放在“准备”和“开始”之间的后台(大约10%的复制率),则会从_storyboard.Begin()内部引发NullReferenceException。当然,它最终会崩溃
我无法确定问题的来源,因为我需要快速修复,所以我决定在这个罕见的场景中捕获这个NullReferenceException。这才是真正问题的起点。我已将“Go”实现更改为:
public void Go()
{
Debug.WriteLine("BreakPoint 1");
try
{
_storyboard.Begin();
}
catch (NullReferenceException)
{
Debug.WriteLine("BreakPoint 2");
}
}
之后,崩溃根本无法再现,但问题是“断点2”从未命中(输出中也没有打印输出)。“断点1”通常也会被命中并打印出来。将NullReferenceException更改为其他异常类型(不是父类型ofc)会导致崩溃重新出现
所以。。。这是怎么回事?是否缓存了此崩溃?那是什么奇怪的行为?假设它将按预期工作是否安全
附加问题:也许你知道为什么最初的代码会崩溃
编辑:
TargetInvocationExceptions的internalException的堆栈结束跟踪如下所示:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.Storyboard_Begin(Storyboard storyboard)
at System.Windows.Media.Animation.Storyboard.Begin()
at X.Go()
我知道您说过您尝试将父类型用于NullReferenceException,但请在不运行调试程序的情况下尝试以下:
public void Go()
{
Debug.WriteLine("BreakPoint 1");
try
{
_storyboard.Begin();
}
catch (Exception)
{
Debug.WriteLine("BreakPoint 2");
System.Diagnostics.Debugger.Break();
}
}
我的怀疑是捕获没有触发,因为您是从调试器中运行的。还可以尝试System.Diagnostics.Debugger.Launch()如果.Break(),则在catch中输入code>代码>不起作用。最后还可以尝试抛出在catch if.Launch()中的code>代码>不起作用
如果调试器在这两种情况下都试图启动,那么您就有了另一个线索
更新:
我不能告诉你发生这种情况的所有原因,因为在你的情况下,可能无法准确确定是什么原因导致了这种情况
由于使用多线程,我见过这样的行为。在连接了调试器的情况下运行时,多线程的行为可能会有所不同。计时问题和竞争条件可以防止在调试器中引发异常,否则在没有附加调试器的情况下可能会频繁发生异常
我还遇到过在第三方代码甚至我的团队代码中使用System.Diagnostics.Debugger.IsAttached
的实例,这些代码导致应用程序根据使用此检查的if
语句表现出不同的行为
最后,我曾经有过这样的经历,我想不出发生这种行为的具体原因。我已经学会了使用System.Diagnostics.Debugger.Break()
方法,无论何时根据是否附加了调试器,我都会看到不同的行为。有时候,这真的只是一种直觉。那么,程序是否仍在崩溃?如果您让它捕获一个通用的异常
会发生什么?它没有崩溃,但看起来好像捕获中的代码没有执行。任何作为NullRefresenceException父级的异常类型都正在修复崩溃。任何其他异常类型都无法修复崩溃。如果您得到的是TargetInvocationException
,那么这就是您需要捕获的。InnerException
属性很可能是您的NullReferenceException
,但您无法捕捉到它(除非您使用的是C#6.0,您可以执行:catch(targetingException ex)when(ex.InnerException是NullReferenceException)
).您对在Go
之前调用Prepare
有多大把握?大约100%确定。两者都只在一个上下文中调用,并且一个接一个地调用。此外,我还检查了Go()中是否有_Storyboardbeeing null,如果这是您所担心的。您是对的,即使调试器没有在断点处停止,也会执行此捕获中的代码。Break()使应用程序在不中断调试器会话的情况下结束。我还尝试从catch块更改一些图形元素,效果非常好。你能解释一下这种行为吗?@Yester我已经用一些额外的信息更新了答案。不幸的是,如果没有您的精确设置和VisualStudio解决方案的副本,我无法给您一个确切的答案,说明为什么在您的情况下会出现这种行为。我在更新后的答案中提供了一些需要查找的内容。不幸的是,您可能不得不承认,您可能无法确定在您的案例中发生这种情况的原因。但是,记住这一事实,当它在另一种情况下再次发生时,你可以试着去识别它。我就是这么做的。谢谢你的帮助。这并不能解释为什么会发生这一切,但这可能是我现在能得到的最好的东西:-)