WPF:运行任务而不干扰动画性能
我们小组阅读了广泛引用的文章 http://blog.quantumbitdesigns.com/2008/07/22/wpf-cross-thread-collection-binding-part-4-the-grand-solution/ 并想知道是否有你们中的一些人可以帮助解决我们的问题:
团队成员有一个正在运行动画的 WPF 应用程序。问题在于,即使在不同的线程上执行后台任务也会导致动画抖动。问题是创建低优先级的常规线程并没有帮助,因为这些任务最终必须在 UI 控件中显示数据。 例如: 我们有一个控件可以显示应用程序正在执行的操作的日志。 有一个单独的 DLL,它有一个 GetLogs 方法,可返回最新日志的列表。 我们使用计时器激活它,应用程序每 500 毫秒就会获取一个新列表,其中最多可包含 10000 个条目。 日志用户控件只是一个绑定到 ObservableCollection 的 ListView。 我们的要求是将我们收到的列表中的每个条目添加到可观察集合中。我们还检查集合是否没有超出我们给定的限制(例如 100000 个条目)。如果超过限制,我们将删除前 10000 个条目。
现在这只能在 UI 调度程序对象中完成,因此最好的关闭解决方案是使用 BackGroundWorker。但该线程的优先级并不低,无法在那里设置优先级。我们想知道这是否会有帮助,因为我们的理解是线程使用 Dispatcher.Invoke 方法发送 UI 元素。
所以这对我来说确实是并行的,使用 Dispatcher.BeginInvoke(ThreadPriority.Low ……) 将每个字符串添加到可观察集合中 这会减慢日志显示速度,而且动画仍然很乱。
对于这样的常见问题(UI 性能和后台任务)是否有开箱即用的解决方案?
Our group read the widely referenced article http://blog.quantumbitdesigns.com/2008/07/22/wpf-cross-thread-collection-binding-part-4-the-grand-solution/ and wondered if any of you could help with our problem:
A team member has a WPF application that has an animation running. The problem is that performing background tasks even on different threads causes the animation to jitter. The issue is that creating a regular thread with a low priority does not help as these tasks eventually have to show the data in the UI controls.
For example:
We have a control that shows logs of what the application is doing.
There is a separate DLL which has a method GetLogs that returns a List of the latest logs.
We activate it using a timer and every 500ms the application gets a new list which can contain up to 10000 entries.
The log user-control is simply a ListView which is bound to an ObservableCollection.
Our requirement is to add each entry from the List we receive to the Observable Collection. We also check that the collection has not exceeded the limit we gave it (say 100000 entries). If it does exceed the limit, we remove the first 10000 entries.
Now this can only be done in the UI dispatcher object so the best close solution is using BackGroundWorker. But this thread does not have a low priority and the priority cannot be set there. We wonder if this will even help since our understanding is that the thread sends the UI elements with Dispatcher.Invoke method.
So this is really parallel for me to add each string to the observable collection with Dispatcher.BeginInvoke(ThreadPriority.Low ……)
This slows up the log display plus the animations are still cranky.
Is there is an out of the box solution for such a common problem(UI performance and background tasks)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是BackgroundWorkerPrioritized 组件的链接,它是一个基本的.NET Framework 实现,通过设置线程优先级进行了改进传递构造函数参数。
希望这有帮助。
Here is the link to BackgroundWorkerPrioritized Component which is a basic .NET Framework implementation improved with setting thread priority by passing the constructor parameter.
Hope this helps.
我不确定你在后台线程中做了什么,但每次你调用 Dispatcher.BeginInvoke 时,你都会在主线程上做一些事情。在你的例子中,每 1/2 秒,你就会在主 UI 线程中执行 10000 件事。由于您更新了 ObservableCollection,每次添加/删除某些内容时也会引发一个事件。
在这种情况下,我不使用可观察的集合,而是使用列表。在后台线程中创建列表,然后通过一次
Dispatcher.BeginInvoke
调用将列表视图绑定到该列表。I'm not sure what your doing in the background thread, but every time you call
Dispatcher.BeginInvoke
, your doing something back on the main thread. In your case, every 1/2 second, your doing 10000 things in the main UI thread. Since your updating anObservableCollection
, your also raising a event every time you add/remove something.In this case, instead of using an observable collection, I'd just use a list. Create the list in the background thread, then bind your listview to that with one
Dispatcher.BeginInvoke
call.