【问题标题】:WPF animation freezes even if I use new Thread即使我使用新线程,WPF 动画也会冻结
【发布时间】:2012-10-25 08:04:45
【问题描述】:

我面临一个大问题:在我的 WPF 应用程序中,MainWindow 包含一个带有加载动画(故事板)的边框。默认情况下它是折叠的。当我加载大量数据或加载新的 XAML 屏幕时,有时会使其可见并折叠。

首先,我根本没有使用线程,动画既冻结又出现迟到。

然后我开始像这样使用线程:

Messenger.StartAnimation();
var task = Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(150);
                }).ContinueWith((a) =>
                {
                    // HERE Screen moving + large amount of data loaded with Entity Framework
                    Thread.Sleep(200);

                    Messenger.StopAnimation();
                }, CancellationToken.None, TaskContinuationOptions.NotOnFaulted, threadUIContext);

这一次,动画在 1 秒内工作,然后它只是冻结,直到所有数据和新显示的屏幕加载完毕。 A 就像主线程阻塞所有线程一样。

我尝试添加 Timer 以将我的 Messenger.StopAnimation() 延迟 3 秒后。当所有内容都被更改并加载到我的新屏幕上时,即使这样我的动画也会冻结 1 秒钟,然后我的动画会持续 3 秒钟。

我尝试了DispatcherBackgroundWorker 并遇到了与以前的代码相同的问题。

我尝试将我的动画放在一个弹出窗口上,甚至放在一个透明的新窗口上。没什么可做的,它总是在停止之前冻结 1 秒钟......

对于信息,我使用ObservableCollection(我尝试过使用列表,同样的问题),我在MainWindowContentControl 内加载不同的屏幕。

我看过 techdays 的视频,速度与激情,我真的很想获得像视频中那样流畅的动画,但冻结似乎无法消除。

【问题讨论】:

  • 你没有提供足够的细节来确定,但是如果你向视图抛出 notifypropertychanged 事件,这些将由主线程处理。所以如果你使用线程来完成工作,但仍然通知更改,主线程仍然会处理这些并被它占用。
  • 您将 ObservableCollection 绑定到哪些控件?你是如何绑定的?如果不绑定,问题会消失吗?我知道如果不显示数据,该应用程序将毫无用处。这是为了隔离是否是渲染问题。

标签: wpf multithreading animation freeze


【解决方案1】:

我们和 Jack 有同样的问题,ListView 绑定到 ObservableCollection。经过大量分析,我们认为是排序和分组过程很慢,而不是对数据库的查询。最后,我们实现了一个单独的线程,但当然必须调用调度程序进行排序和分组,这会将长时间运行的操作放回主 UI 线程 - 所以这似乎淹没了我们漂亮的“正在加载..”动画 - 出现让用户挂起和生涩 - 这根本不是我们想要的......正如 Akku 所说,除了改变数据的显示方式之外,我没有看到解决方案。

【讨论】:

    【解决方案2】:

    在一个简单的集合视图中加载 50 多个小图像时,我遇到了同样的问题。我最终发现,将位图绘制到屏幕上的 .NET Framework 是绑定主线程的原因,而我完全没有办法绕过它。我尝试将所有元素放在视图中,但慢慢填充绑定到视图的集合,但是每次可观察集合发生更改时,.NET Framework 都会重新绘制视图中的所有图像,所以这也无济于事。

    我向一位微软工程师询问过这个问题,他直言不讳地承认这是 .NET Framework 中的一个问题,未来必须由微软来解决。我的一位同事说,您可以通过自己使用自己的算法绘制所有像素来规避这个问题。

    我想如果你想解决这个问题,你将不得不改变你的数据显示方式,尽管我无法帮助你解决这个问题。

    【讨论】:

    • 您可以通过使用 WriteableBitmap 并在一个大位图中绘制所有单独的位图来解决此问题,如果有更改,则仅更改大位图的该部分,然后为该特定添加一个dirtyrect地区。 MainThread 只会重绘dirtyrect。
    • 这完全与问题无关。这与 .NET 控件的更新速度有关。此外,我使用控件是有原因的(除了每个图像之外,我还有按钮和许多其他东西),但这只是说明我遇到了 .NET 框架的限制的情况。但是感谢您给出 -1 来说明我的问题上下文应该有所不同 - 虽然我仍然认为我的回答几乎总结了 Fulg 卡在这里的问题。
    • 我刚刚评论了您的问题(因为我认为它可能对您有帮助)。我知道我的评论与问题无关。所以我没有-1,是别人做的。
    • 是的,我想说这是 .NET 框架的问题并不是最好的答案。当我向微软工程师询问我的问题时,从微软工程师那里得到“这是一个 .NET 问题”的答案也让我想把 -1 改组给微软。
    猜你喜欢
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多