即使我使用新线程,WPF动画也会冻结

时间:2012-11-05 13:14:55

标签: wpf multithreading animation freeze

我面临一个大问题:在我的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就像主线程阻塞所有线程一样。

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

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

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

有关信息,我使用ObservableCollection(我已尝试使用List,同样的问题)并在ContentControl的{​​{1}}内加载不同的屏幕。

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

2 个答案:

答案 0 :(得分:1)

在简单的集合视图中加载50多个小图像时遇到了同样的问题。我最终发现,.NET Framework将位图绘制到屏幕上是主线程的关键所在,而我绝对无法绕过它。我尝试将所有元素放在视图中,但是慢慢填充绑定到视图的集合,但每次更改observable集合时,.NET Framework都会重新绘制视图中的所有图像,因此这也没有用。

我向微软工程师询问了这个问题,他直截了当地承认,.NET框架中的一个问题将来必须由Microsoft修复。我的一位同事说,你可以通过自己的算法自己绘制所有像素来规避这个问题。

我想如果你想解决这个问题,你必须改变你的数据显示方式,尽管我可以帮助你解决这个问题。

答案 1 :(得分:0)

我们遇到与Jack相同的问题,ListView绑定到ObservableCollection。经过大量分析后,我们认为排序和分组的过程很慢,而不是对数据库的查询。最后我们实现了一个单独的线程,但当然不得不调用调度程序进行排序和分组,将长时间运行的操作放回到主UI线程上 - 这样看起来已经淹没了我们不错的“Loading ..”动画 - 它出现了让用户挂起并且生涩 - 不是我们想要的......正如Akku说的那样,除了改变数据的显示方式之外,我没有看到解决方案。