调度程序与多线程
根据具有长时间运行计算的单线程应用程序 MSDN示例,有一个只需 1 个线程即可创建响应式 GUI。感谢 Dispatcher
对象,我们可以设置工作项的优先级。
我的问题是,如果可能的话,在后台线程中执行简单任务(假设我们只有 1 个单核 cpu)有什么意义?
谢谢
According to Single-Threaded Application with Long-Running Calculation MSDN example, there is a possibility of creating a responsive GUI in just 1 thread. Thanks to the Dispatcher
object, as we can set the Priority of work items.
My question is, what sense does it have to do simple tasks (supposing we just have 1 single core cpu) in a background thread when this is possible?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
本质上,该示例将“找到尽可能多的素数”这一单一任务分解为许多快速运行的单独步骤,这些步骤以非常低的优先级执行,因此它们不太可能中断用户与该任务的交互。窗户。
我觉得一个缺点是它迫使程序员将任务分解为许多小步骤,我们必须保证这些小步骤可以快速执行。当其中一项任务运行时,它会在整个运行期间阻塞 UI。考虑下载文件。连接到 FTP 站点的单个步骤可能需要 20 秒或更长时间,在此期间 UI 会被冻结。
将此与一次性完成整个下载、将更新编组回 UI 线程的正确线程进行比较。即使在单核机器上,这也应该提供合理的用户体验。
下一个缺点是您现在在单个线程上执行代码。这并不像听起来那么好。由于小型单独任务的排队方式,其他任务(推送到窗口消息队列上的任何任务)都有机会跳入其中并在其中执行。如果您的特殊任务使用的状态没有正确隔离,您可能会遇到看起来像线程问题但实际上并非如此的问题,更糟糕的是,您无法使用锁定来保护自己免受这些问题,因为操作在同一线程上执行。使用 Application.DoEvents() 时也有类似的缺点(尽管有一些额外的令人讨厌的东西可以继续,但这里不能继续)。
因此,您概述的技术可能适用于某些情况,也可能不适用于某些情况。因此,我会选择始终适用的技术,即在后台线程上运行代码。
我认为对于大多数“使用单线程同时保持 UI 响应问题”来说,答案通常是相同的。你真的不能。你必须硬着头皮学会正确穿线。认真思考,隔离您的状态,使用不变性和锁定保护状态,并在需要时在线程之间正确编组调用。
Essentially the example has broken up the single task of 'finding as many prime numbers as you can' into many, many fast running individual steps that are executed at a very low priority, so that they're unlikely to interrupt a user interacting with the window.
One drawback I feel is that it forces the programmer to break up a task into many small steps that we have to guarantee can be executed quickly. When one of those tasks is running, it's blocking the UI for the entire duration of it. Consider downloading a file. Taking the single step of connecting to an FTP site could take 20 seconds or more, during which time the UI is frozen.
Compare this with a proper thread doing the whole download in one go, marshalling updates back to the UI thread. Even on a single core machine this should provide a reasonable user experience.
The next drawback is that you're now executing code on a single thread. This isn't as great as it sounds. Because of the way that the small individual tasks are being queued, other tasks (anything pushed onto the window's message queue) have a chance to jump in and execute in amongst them. If the state that your special tasks use is not properly isolated, you can get issues that look like threading issues but aren't, and worse still, you cannot protect yourself from those issues using locking, as all actions are performed on the same thread. There are similar drawbacks when using Application.DoEvents(), (although there's some extra nasty stuff that can go on with that which can't go on here).
So the technique you outlined may be usable for some situations, and for some maybe not. I'd therefore go for the technique which is always applicable, which is running the code on a background thread.
I think the answer is usually the same for most 'use a single thread whilst keeping the UI responsive questions'. You can't really. You have to bite the bullet and learn to thread properly. Think hard, isolate your state, protect state using immutability and locking, and marshal calls properly betweeen threads where needed.