多个 Control.BeginInvoke/Invoke 调用会按顺序执行吗?
我需要知道 Control.BeginInvoke 和 Control.Invoke 调用是否会按照调用顺序执行。
我有以下场景:
- UI 线程被阻塞
- WCF 线程调用 Control.BeginInvoke
- WCF 线程调用 Control.Invoke (或者可能再次 BeginInvoke)
- UI 线程被解除阻塞
- ?
步骤 1-4 的执行顺序保证按照所示顺序(从技术上讲,顺序不能保证是这样,但我的问题仅在顺序如图所示时才相关)。
我的问题是,步骤 3 中的 Invoke/BeginInvoke 调用是否有可能在步骤 2 中的 BeginInvoke 调用之前执行?
另外,请不要评论阻塞 UI 线程。
I need to know whether Control.BeginInvoke and Control.Invoke calls will execute in the order they are called.
I have the following scenario:
- UI thread is blocked
- WCF thread calls Control.BeginInvoke
- WCF thread calls Control.Invoke (or possibly BeginInvoke again)
- UI thread is unblocked
- ??
The execution order of step 1-4 is guaranteed to be in the shown order (technically the order is not guaranteed to be that way, but the question I have is only relevant if the order is as shown).
The question I have is whether there is any chance that the Invoke/BeginInvoke call in step 3 is executed before the BeginInvoke call in step 2?
Also, please don't comment on blocking the UI thread.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在您的情况下,步骤 2 将始终在步骤 3 之前执行。UI 线程上的 BeginInvoke 将按照排队的顺序执行。
UI线程实际上是一个消息泵,它有一个消息队列,只有一个线程使用它,因此可以保证工作项将按照它们排队的顺序执行。
使用 Delegate.BeginInvoke 时,执行顺序可能是非顺序的。
In your case, step 2 will always execute before step 3. BeginInvoke on the UI thread will execute in the order it has been queued.
The UI thread is in fact a message pump, it has a single message queue with only one thread consuming it, so it's guaranteed that work items will be executed in the order they were queued.
It's with Delegate.BeginInvoke that the order of execution may be non-sequential.
BeginInvoke 调用在目标线程上排队(因为它们按到达顺序发布)。
WCF 线程上的同步调用(步骤 3)可以在从此线程进行的异步调用(步骤 2)之前执行。
BeginInvoke calls are queued on the destination thread (as they are posted in order of arrival).
Synchronous calls on the WCF Thread (step 3) may be executed before asynchronous calls (step 2) made from this thread.
没有足够的信息来给你一个好的答案。 UI 线程被阻止,因此步骤 2 和 3 必须在不同的线程上运行。如果两者之间没有同步,那么我们如何知道任何顺序?
你有很多并行性,但从你所描述的情况来看,我们不可能告诉你会发生什么可能的顺序,除非说“任何事情”。我们甚至无法告诉您在 UI 线程被阻塞之前或 UI 线程解除阻塞之后不会发生对 BeginInvoke 的调用。
Not enough information to give you a good answer. The UI thread is blocked so steps 2 and 3 must be running on a different thread. If there's no synchronization between the two, then how could we know any ordering?
You've got a lot a parallelism going on, but from what you've described, there's no possible way we could tell you what possible orderings will occur, short of saying, "Anything." We can't even tell you that the calls to BeginInvoke won't happen before the UI thread is blocked or after the UI thread is unblocked.
您不可能假设这一点,但如果上述两个调用之间确实存在某种形式的依赖关系,则让它们等待信号量,并且仅在它们都完成时才执行依赖代码。
如果您同时进行两个调用的原因不是性能,那么我可能会在第一个调用的回调中执行第二个调用(使其更容易调试)。
No chance you can assume that but if there's actual some form of dependency between the two calls above have them waiting on a semaphore and only execute the dependent code when they're both completed.
If the reason why you're making the two calls at the same time is not performance then I would probably just execute the second call in the callback of the first (makes it a lot easier to debug).