与Multi-Touch Manipulations相关的未记录的.NET代码抛出异常

时间:2014-08-22 14:18:59

标签: c# .net wpf windows multi-touch

有利的结果是防止这种例外,最好是,或者至少优雅地处理它。

我在 Microsoft代码中抛出了异常。最重要的是,抛出异常的方法是System.Windows.Input.Manipulations.ManipulationSequence.ProcessManipulators,这是我在Microsoft Reference Source中找不到的。

当抛出异常时,我可以看到它引用的调用堆栈窗口中的一行Windows.Input.Manipulations.ManipulationProcessor2D.ProcessManipulators, which does exist in Microsoft Reference Source.

但是正如你所看到的,它没有有一个名为ManipulationSequence的兄弟类。

对于例外本身,它是System.Argument.OutOfRangeException,其值为Timestamp values must not decrease. Parameter name: timestamp Actual value was 6590630705479.

抛出异常的方法的完全限定签名是System.Windows.Input.Manipulations.ManipulationSequence.ProcessManipulators(long timestamp, System.Collections.Generic.IEnumerable<System.Windows.Input.Manipulations.Manipulator2D> manipulators, System.Windows.Input.Manipulations.ManipulationSequence.ISettings settings)

似乎one other person in the universe出现了这个问题,但根据唯一的评论无法复制。

我在画布上有6个MediaElement个对象,这些对象在被操作时都在运行视频,因此我觉得它可能与CPU被征税和减速有关,可能会将时间戳发送到方法乱序(虽然使用Image而不是MediaElement时会出现同样的问题)。异常偶然发生,有时会在几秒钟之后乱搞对象,有时可能需要几分钟或更长时间来处理对象。

我在ManipulationDelta内进行实际操作的代码如下所示:

//Get current values to manipulate
TransformGroup group = (TransformGroup)element.RenderTransform.Clone();
TranslateTransform translate = (TranslateTransform)group.Children[0].Clone();
ScaleTransform scale = (ScaleTransform)group.Children[1].Clone();
RotateTransform rotate = (RotateTransform)group.Children[2].Clone();

//...does manipulations on each by changing values...

//Apply transformation changes
group.Children[0] = translate;
group.Children[1] = scale;
group.Children[2] = rotate;
element.RenderTransform = group;

我在XAML中Storyboard弄乱了RotateTransform,因此我无法真正使用MatrixTransform

我使用WPF和.NET 4.5.1创建它。 Windows 8.1和Windows 7中都会出现此错误。有关如何防止此异常发生的任何想法吗?


我在调查问题时有些想法:

  • 我也可以在这里玩ManipulationInertiaStarting 造成这种错误的原因。
  • 我刚刚将e.Handled = true;添加到ManipulationCompleted的末尾,之前不存在。我没有得到错误(虽然,再次,非常零星,因此很难判断它何时修复)。
  • 如果ManipulationDelta方法尚未完成,并且从用户输入再次被击中,是否会出现某种竞争条件,其中第一种方法命中缺乏CPU资源而第二种方法通过,那么当第一个方法最终完成时,创建的时间戳是过去的吗?
    • 根据评论,这不太可能。
  • 我与同事交谈以获得更好的理解。他帮助我意识到我无法从处理操作事件的方法中吞下异常,因为异常在它到达之前发生,在实际创建操作数据时。因此,我可以处理异常的唯一地方是App.Main()(我的代码存在的调用堆栈中的第一个位置),这使得处理它变得更加困难。

2 个答案:

答案 0 :(得分:1)

我自己有这个问题。 经过大量测试后,可以在较重的负载下使用较慢的机器进行复制。

该应用程序用于数字标牌,并显示了许多不同的项目(视频,Html,图像等),还有一些动画。

我不确定,但似乎是及时处理输入事件的问题。

对于我自己,我可以“解决”这个问题,将代码从操作外包到其他代码异步,也可以在性能方面分析和重写代码。(尽可能缩短在事件内部运行的路径并完成所需的一切稍后再做一个任务)

我还在我的应用程序中添加了一个Exceptionhandler来“忽略并记录”这个问题,因为它没有其他影响。

欢迎与我联系以获取更多信息。

PS:这是我在这里的第一个答案,所以我希望我写的方式没问题

答案 1 :(得分:0)

在为WinRT开发时遇到了类似的问题。

有时可以使用DispatcherUnhandledException事件来忽略一个特定的异常。为此,添加事件侦听器,检查是否是您想要的异常(因为抑制所有异常通常是个坏主意),然后设置Handled属性。