其他分享
首页 > 其他分享> > Catch不执行其代码

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