繁重的 TPL 后台线程会在 WPF 的 UI 线程中产生滞后
我有一个 WPF 应用程序,它使用多个后台线程来预编译 LINQ 查询并预缓存一些值,稍后将需要这些值。 TPL 用于通过以下方式启动这些任务:
var newTask = new Task(taskAction, myCancelToken, TaskCreationOptions.LongRunning);
newTask.Start();
这有效,任务分布在多个 cpu 核心等上。但是,这些线程会导致高 cpu 负载,这在 UI 中是可以察觉的,只要线程尚未完成。
那么,什么是平滑 UI 的合理方法呢?通过研究我发现,不应该给线程特殊的优先级。其他人的意思是,频繁使用 Thread.Sleep() 是可行的方法,这对我来说似乎有点过时和老套。
还有其他我不知道的方法吗?确定线程优先级是否有真正的缺点(据我所知,这不可能直接通过 TPL 实现)?
提前致谢!
I have a WPF-application that uses several background threads for precompiling LINQ-queries and precaching some values, that will be needed later. TPL is used to start these tasks by:
var newTask = new Task(taskAction, myCancelToken, TaskCreationOptions.LongRunning);
newTask.Start();
This works, the tasks are distributed over several cpu cores etc. However, these threads cause a high cpu load, that is perceptible in the UI, which tends to stumble or even freeze, as long as threads aren't finished.
So, what could be a reasonable way to smoothen UI. By researching I found, that one's not supposed to give threads special priorities. Others mean, frequent use of Thread.Sleep() was the way to go, which seems a bit outworn and hacky to me.
Are there additional ways I'm not aware of? Are there real disadvantages of priorizing threads (which isn't possible via TPL directly, afaik)?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于任务的优先级,你可以这样做
http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/01/29/how-to-schedule-task-on- Different-thread-priority.aspx
但据我所知,不建议显式更改线程优先级
Concerning prioritizing of tasks, you could do smth like
http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/01/29/how-to-schedule-task-on-different-thread-priority.aspx
But AFAIK explicit changing of thread priority is not recommended practice
对于 4 核机器来说,10 个线程太多了。如果它们像预编译查询一样受计算限制,那么它们都会争夺 CPU 时间,并使整个机器无响应。
我建议您使用Environment.ProcessorCount来了解有多少个核心可用,并且一次仅启动(该数字 - 1)个线程。您可以确定首先运行的工作的优先级,并将其他工作作为继续进行排队。
这将留下一个空闲的核心来为您的 UI 线程提供服务,并且应该使应用程序再次响应。
10 threads is too many on say a 4-core machine. If they are compute-bound like pre-compiling queries, they will all be contesting for cpu time and will make the whole machine unresponsive.
I suggest you use
Environment.ProcessorCount
to find out how many cores are available, and only start ( that number - 1 ) threads at a time. You can prioritise which work runs first and queue the others as continuations.This will leave a core free to service your UI thread and should make the app responsive again.