等待使用 Display::asyncExec() 提交给 SWT UI 线程的所有 Runnable 完成
有没有办法等待通过 asyncExec(...) 提交到 SWT UI 线程的所有 Runnable 完成?
背景:
我有一个长时间运行的操作,除其他外,它还触发以下事件:依次通过 Display 的 asyncExec(...) 实例方法将 Runnables 提交到 SWT UI 线程。
长时间运行操作的进度显示在 ProgressMonitorDialog 中,我想仅在 UI 线程完成执行 Runnables 后才关闭该对话框。
将调用从 asyncExec(...) 更改为syncExec(...) 不是一个选项,因为当从其他上下文触发事件时,不需要后者。
Is there a way to wait for all Runnables submitted to the SWT UI Thread via asyncExec(...) to finish?
Background:
I have a long-running operation, which among other things is triggering events that in turn submit Runnables to the SWT UI thread via the asyncExec(...) instance method of Display.
The progress of the long-running operation is shown in a ProgressMonitorDialog, and I would like to close the dialog only after the UI thread has finished executing the Runnables.
Changing the calls from asyncExec(...) to syncExec(...) is not an option, as the latter is not desired when the events are triggered from other contexts.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
org.eclipse.swt.widgets.Display.readAndDispatch() 将处理事件队列中的事件,如果没有更多事件需要处理,则返回 false。但您可能不想在它处理事件时使用它。
asyncExec(*)
是一个 FIFO 队列(尽管操作系统图形事件取代了 asyncExec),因此您可以完成大部分长时间运行的操作处理,然后将最终的 asyncExec 放入队列中:理论上,当您到达最后一个操作时,从长时间运行的操作中生成的所有其他 asyncExec 都将完成。
编辑:潜在的其他选项
创建您自己的
org.eclipse.core.runtime.jobs.Job
,然后在最后join()
:要使用它,请在每次要触发事件时递增()它,并让它们在完成时递减它(您必须确保无论抛出什么异常,它们都会递减它:-)
org.eclipse.swt.widgets.Display.readAndDispatch()
will process an event from the event queue and returnfalse
if there are no more events to process. But you probably don't want to use this as it processes an event.asyncExec(*)
is a FIFO queue (although OS graphics events supersede the asyncExecs), so you could do most of your long-running op processing and then place a final asyncExec in the queue:In theory, all of the other asyncExecs spawned from your long running op will be finished by the time you get to the last one.
EDIT: potential other option
Create your own
org.eclipse.core.runtime.jobs.Job
and thenjoin()
it at the end:To use it, increment() it every time you are going to fire off events, and have them decrement it when they're done (You have to make sure they decrement it no matter what exception is thrown :-)
谢谢,我最终得到了以下结果。我认为这是一个非常干净的解决方案。顺便说一句,如果我有足够的声誉,我会投票给你的答案:)
Thanks, I ended up with the following. I think it is a pretty clean solution. By the way I would upvote your answer if I had enough reputation for that :)