2011-04-27 106 views
2

当我向Canvas添加很多项目时,UI为什么会冻结?假设我有一个从1到1000的循环。所有1000个元素都添加后,我只能看到所有元素。为什么Canvas不显示项目,因为它们一次添加或删除一个项目?如何阻止用户界面冻结?

我能做些什么来达到这种效果?我想为元素添加动画,因为它们一次添加到Canvas中。但是由于界面刚刚冻结,动画并未显示出来。

感谢提前:)

+1

您可能会发现可以回答这个问题不太相关:http://stackoverflow.com/questions/4188766/how-do-i-block-access-to-a-method-until-animations-are -complete/4199546#4199546 – AnthonyWJones 2011-04-27 12:00:22

回答

1

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

在有很多在画布上的形状的一个项目,我发现这是很有帮助的预分配,并在开始添加所有的形状,然后只需拨动自己的知名度。我不知道这是普遍有用的或只是特定于。

+0

由于我添加了1000个项目,计时器会严重影响性能。没有计时器也需要4-5秒才能建立起来。定时器会恶化情况。我可能会删除动画而不是性能瓶颈。 – TCM 2011-04-28 15:03:22

0

您的代码被UI线程(即更新屏幕在同一线程)上执行的情况下,我是。因此,当您执行任何计算密集型操作时,您的UI将冻结。长时间运行的操作必须在单独的线程中运行,以便应用程序保持响应。开始一个新的线程,并从你的线程中迭代你的循环并实例化你的对象。将对象添加到画布上,你将不得不使用一个Dispatcher确保代码部分UI线程上运行。

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

应该使用什么线程来创建MyElement的实例?当有大量的UI操作达到目标时,你实在别无选择,只能在UI线程上执行它们。 – AnthonyWJones 2011-04-27 11:52:31

+0

您必须提前实例化项目并将它们存储在列表中。然后,您可以将项目分派到其他线程中的画布上。即 DoWork的的doWork =委托(诠释J) { Canvas.Children.Add(矩形[J]); }; 螺纹的WorkerThread =新主题(新的ThreadStart(()=> { 对(INT I = 0; I <1000;我++){ Dispatcher.BeginInvoke(的doWork,I); Thread.sleep代码(100); } })); workerThread.Start(); – Steve 2011-04-27 14:37:27