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

jpo*_*luk 13 .net c# windows wpf multi-touch

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

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

抛出异常时,我可以在它引用的Call Stack窗口中看到一行Windows.Input.Manipulations.ManipulationProcessor2D.ProcessManipulators,这在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)

似乎宇宙中的另一个人遇到了这个问题,但根据唯一的评论它无法复制.

MediaElement在画布上有6个对象在操作时都运行视频,所以我觉得它可能与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;
Run Code Online (Sandbox Code Playgroud)

我有一个Storyboard在XAML搞乱了RotateTransform,所以我不能真正使用MatrixTransform.

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


我调查问题的一些想法:

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

小智 1

我自己也遇到过这个问题。经过大量测试后,它可以在重负载下用较慢的机器重现。

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

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

对于我自己来说,我可以通过外包代码从异步操作到其他代码以及分析和重写代码性能来“解决”这个问题。(尽可能缩短在事件内部运行的路径,并在以后完成所有需要做的事情有任务)

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

请随时与我联系以获取更多信息。

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