【问题标题】:How can I stop the UI from freezing?如何阻止 UI 冻结?
【发布时间】:2011-04-27 02:56:26
【问题描述】:

当我向 Canvas 添加许多项目时,为什么 UI 会冻结?假设我有一个从 1 到 1000 的循环。在添加所有 1000 个元素后,我只能看到所有元素。为什么 Canvas 在一次添加或删除一个项目时不显示它们?

我可以做些什么来达到这个效果?我想为元素设置动画,因为它们一次一个地添加到 Canvas 中。但是动画没有显示,因为 UI 只是冻结了。

提前谢谢:)

【问题讨论】:

标签: silverlight silverlight-4.0 silverlight-3.0


【解决方案1】:

也许您可以使用计时器,并在每个刻度上添加较少数量的元素?这可以让您确保在每次添加之间进行几次刷新。

在一个画布上有很多形状的项目中,我发现在开始时预先分配和添加所有形状很有帮助,然后只需切换它们的可见性。我不知道这是否普遍有用,或者只是针对我所处的情况。

【讨论】:

  • 计时器会严重影响性能,因为我要添加 1000 个项目。如果没有计时器,建立起来也需要 4-5 秒。计时器会使情况恶化。我可能会移除动画而不是性能瓶颈。
【解决方案2】:

在 VB.NET 中,我们使用 Application.DoEvents(),但我觉得在 Silverlight 中是不可能的。

阅读这篇文章:http://forums.silverlight.net/forums/p/12015/38635.aspx

希望这有帮助!

【讨论】:

    【解决方案3】:

    您的代码正在 UI 线程(更新屏幕的同一线程)上执行。因此,当您执行任何计算密集型操作时,您的 UI 将冻结。长时间运行的操作必须在单独的线程中运行,以使应用程序保持响应。启动一个新线程,并从您的线程内遍历您的循环并实例化您的对象。要将对象添加到画布,您必须使用 Dispatcher 以确保部分代码在 UI 线程上运行。

    MyElement element = new MyElement();
    Dispatcher.BeginInvoke(() => AddElementToCanvas(element));
    

    【讨论】:

    • 应该使用哪个线程来创建MyElement 的实例?当需要完成大量 UI 操作时,您真的别无选择,只能在 UI 线程上执行它们。
    • 您必须提前实例化项目并将它们存储在列表中。然后,您可以在其他线程中将项目分派到画布上。即 DoWork doWork = delegate(int j) { Canvas.Children.Add(rectangles[j]); };线程 workerThread = new Thread(new ThreadStart(() => { for (int i = 0; i
    猜你喜欢
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多