Catch不执行其代码
作者:互联网
我正在为Windows Phone 8.1(Silverlight)开发C#应用程序.最近,我遇到了与应用程序入睡和情节提要有关的问题.
构造如下:
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.当然,它最终会崩溃.
我无法确定问题根源,因为我需要对此进行快速修复,所以我决定在这种罕见的情况下仅捕获此NullRefereneceException.这是真正的问题开始的地方.我将“执行”实现更改为:
public void Go()
{
Debug.WriteLine("BreakPoint 1");
try
{
_storyboard.Begin();
}
catch (NullReferenceException)
{
Debug.WriteLine("BreakPoint 2");
}
}
之后,崩溃根本无法重现,但问题是“ BreakPoint 2”从未命中(在Output中也没有打印输出).通常也打“ BreakPoint 1”并打印.将NullReferenceException更改为其他Exception类型(不是父类型的c)会导致崩溃重新出现.
所以…这是怎么回事?此崩溃是否已缓存?那是什么样的怪异行为?可以安全地假定它会按预期工作吗?
附加问题:也许您知道为什么原始代码最初会崩溃?
编辑:
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();不起作用.最后还要尝试抛出;如果.Launch();不起作用.
如果调试器在任何一种情况下都尝试启动,那么您会有另外一条线索.
更新:
我无法提供所有可能导致这种情况发生的原因,因为可能无法准确确定造成您情况的原因.
由于使用了多线程,我已经看到了类似的行为.在连接调试器与不连接调试器的情况下,多线程的行为可能有所不同.时间问题和竞态条件可以防止在调试器中引发异常,否则在未连接调试器时可能经常发生异常.
我还遇到了在第三方代码甚至我的团队的代码中使用System.Diagnostics.Debugger.IsAttached的实例,这些代码导致应用程序基于使用此检查的if语句而表现不同.
最后,我有时无法提出导致该行为发生的具体原因.每当我看到根据所连接的调试器是否出现不同的行为,就已经学会使用System.Diagnostics.Debugger.Break()方法.有时确实只是一种直觉.
标签:windows-phone-8-1,c,silverlight 来源: https://codeday.me/bug/20191028/1949403.html