2011-11-24 264 views
2

假设我有两个事件A和B.他们每个人都引发异步调用,比如AsyncA和AsyncB。如何等待异步调用完成?

我想要的是:当A仅在AsyncB完成时调用AsyncA。

事件A和B按顺序依次触发:A,然后B. 我预计AsyncA在AsyncB完成之前完成,但实际上大部分时间,AsyncB在AsyncA之前完成。

我不能在AsyncA完成的事件中放置AsyncB调用。 如何确保AsyncB始终在AsyncA之后?

+1

你能解释为什么你不能在AsyncA完成的处理程序中调用AsyncB吗? –

+0

+1这个经典问题。我想你必须让某个房间“以某种方式”在AsyncA完成的事件上调用AsyncB。 –

+0

因为事件A和B被不同的地方从不同的理由解雇了。 – KentZhou

回答

0

如果顺序比异步方法调用不重要,

+0

您不能对SL –

+0

进行同步呼叫,以防他的方法边界出错 – Jason

+0

无法从SL调用WCF服务?我不这么认为。 – KentZhou

0

只要两个调用异步运行,它就无法控制它们的顺序。这由调度程序完成。

但是你可以使用TPL有他们两个同步运行:

System.Threading.Tasks.Task.Factory.StartNew(() => OnAsyncA()) 
    .ContinueWith((t) => OnAsyncB()); 
+0

这是一个蛮力的方法,我认为问题可以而且应该围绕着设计。也就是说,设计它以便B不依靠A完成。这可能意味着将所有代码凝结成方法A – Jason

+0

我不知道为什么这种方法是蛮力的。但我同意更好的设计可以避免这些问题。 – PVitt

+0

蛮力因为你使用代码来解决设计问题 – Jason

0

不能保证台异步调用的完成顺序,但你可以执行工作要在为了做你要。你需要的是一种同步的方式。

OnAsyncA您需要:

  1. 你需要做,如果有必要节省OnAsyncB所需的信息的工作。
  2. 设置等待手柄(例如ManualResetEventAutoResetEvent)。

OnAsyncB

  1. 保存任何信息所需(例如,结果)。
  2. Spawn a threadpool thread。 (因为WCF回调发生在UI线程上,所以在处理程序中等待信号将是一个坏主意)。

在线程池线程,

  1. 等待句柄。
  2. 完成您通常为OnAsyncB所做的工作。

还有其他的变化,比如有一个更长的运行线程从“依赖事件”队列中出队,使用TPL等等。

记住要从线程池线程同步回UI线程。