14

我在我的 WPF 应用程序中遇到了一个非常棘手的缺陷,无法追踪。错误信息是:

无限循环似乎是由于在布局/渲染过程中反复使 TimeManager 无效而导致的。

堆栈跟踪(对于它的价值)是:

在 System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) 在 System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget) 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 在 MS .Internal.Threading.ExceptionFilterHelper.TryCatchWhen(对象源,委托方法,对象参数,Int32 numArgs,委托catchHandler)

这是一个间歇性缺陷,我唯一能捕捉到它的地方是我捕获 Application_DispatcherUnhandledException 消息的应用程序配置文件中。我在我的应用程序中拥有的所有内容都包含在 try catch 块中,但这最终会出现在捕获未处理异常的地方。

有没有人对此有任何见解?我在互联网上搜索了一些东西,但什么也没找到,我想也许这里的某个人可能对如何追踪它有一些见解或想法。目前,我正在吞下这个异常并让应用程序继续运行,因为它似乎对它没有任何影响(除了让它崩溃)。

4

3 回答 3

4

预计您将无法在代码中捕获异常:您的错误来自应用程序的 Xaml 部分,很可能来自动画。

因此,无论您是在 Xaml 中还是使用代码创建动画,例如,当动画 B 停止时触发动画 A 开始,并且在动画 A 开始时触发动画 B 停止。所以你有一个无限循环:A 开始 -> B 停止 -> A 开始 -> B 停止 -> ...

实际上有许多无限循环的情况。它们可能由 CurrentStateInvalidated 处理程序或 Completed 处理程序或 CurrentTimeInvalidated 触发,并且我可能会忘记使用其他类型的触发器(鼠标、...)和/或前面提到的三种触发器的某些场景。可能代码太复杂了。

删除所有动画以测试此场景。

尝试有一种清晰的方法来重现错误并检查哪些处理程序可能参与这样的循环并无休止地相互调用自己。

...您还可以在处理程序中使用计数器,例如,一个复选框警告您已达到给定(大)数量的调用。此复选框还将给出处理程序的名称。单击确定几次以检查循环“成员”。
您可以在发布版本中保留类似的代码并写入日志文件,只写入一次,当达到该数字时,处理程序将始终在执行任何操作之前返回。比崩溃好。

...或者只是代码审查可能会向您展示可能的循环。

希望这可以帮助。

编辑:请听我的建议:

A ) 删除所有动画,测试应用程序,看看会发生什么。B ) 如果你看不到更多的错误:这就是原因。

C ) 然后,在动画中,尝试移除最“危险”的触发器,即事件触发器。您可以使用 将 XAML 放入注释中,因此只需在动画后复制触发器即可。

D)再次测试:如果你没有看到更多的错误,这是一个事件触发器 E)检查所有的事件触发器并观察我上面描述的循环。

如果在 D) 中您仍然看到错误,请在 C) 处重复使用其他触发器(属性触发器/数据触发器)


其次:它可能是一个属性/数据触发器,其中一些数据经常变化......


也许发布一些xaml。


我有一个想法:尝试在 Application_DispatcherUnhandledException 中设置断点。然后观察内部异常的内部异常......直到到达 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen。例外,那么您可以知道来源。我不会感到惊讶的是导致问题的 Infragistics 网格。我曾经测试过 Telerik 的控制,在解决了一些可怕的问题之后,我回到了我自己定制的经典网格:既节省了金钱又节省了时间。我很快就看到了这个网格:它们就像你的转换器问题或这个网格的自定义样式。--> 如果可能,尝试使用标准 DataGrid。
--> 如果没有错误,我们有根本原因:尝试“裸”基础架构,然后测试,然后添加样式,然后测试。我不确定您是否可以在没有转换器的情况下进行测试。仍然可以让视图模型公开“转换后的”属性......

再次:在您的帖子中,引用您的一些 xaml,描述失败案例。

于 2013-02-12T11:56:10.810 回答
-1

有时异常非常棘手。建议之一是有一个没有异常对象的 catch 块。因此,您可以从以下位置更新您的 catch 块:

 catch(Exception ex)
{
..
}

    catch()
{
..
}

如Peli回复中提到的,还有其他难以捕获的低级异常

于 2013-02-13T10:38:44.990 回答
-1

你已经解决了你的问题吗?我正在研究一点,听起来您正在使用 Infragistics 的第三方控件,对吗?

http://help.infragistics.com/doc/WinForms/2014.2/CLR4.0/?page=Infragistics4.Win.UltraWinStatusBar.v14.2~Infragistics.Win.UltraWinStatusBar.TimerManager.html

他们能在这个问题上帮助你吗?

于 2014-10-17T22:27:29.957 回答