一开始就理解异步,尤其是回调是很困难的。在您的示例中,您做出了不正确但自然的假设...
public static Object LoadInfo()
{
var service = new SomeWcfService();
service.BeginGetInfo(CallbackMethod, service);
// HOW TO GET INFROMATION FROM CALLBACK??
// ERROR: You assume you have more work to do in this method,
// or that this is the place to return your results.
return INFORMATION;
}
您在下面给出的方法是返回结果后进行工作的地方:
private static void CallbackMethod(IAsyncResult ar)
{
// HOW TO PASS INFROMATION TO LoadInfo??
// OOPS! No need to pass pack to LoadInfo - it's done...
var INFORMATION = (ar.AsyncState as SomeWcfService).EndGetInfo(ar);
}
相反,你会想要这样的东西
public static void LoadInfo()
{
var service = new SomeWcfService();
// begin an asynchronous service call
// and handle the results in another method, "CallbackMethod"
service.BeginGetInfo(CallbackMethod, service);
// You can do other, non-service related,
// things here while the service call executes
}
然后您的其他方法处理所有结果:
private static void CallbackMethod(IAsyncResult ar)
{
var results = (ar.AsyncState as SomeWcfService).EndGetInfo(ar);
// Do whetever you need with results here
}
正如威尔在他的出色回答中指出的那样(+1,好像他需要它,哈哈!),您可以使用带有 lambda 表达式的匿名方法,而不是使用单独的回调方法,例如:
public static void LoadInfo()
{
var service = new SomeWcfService();
// begin an asynchronous service call
// and handle the results in this anonymous method
service.BeginGetInfo(x =>
{
// B. This code block will be called when the service returns with results
var results = (ar.AsyncState as SomeWcfService).EndGetInfo(ar);
// Do whetever you need with results here
}, service);
// A. You can do other things here while the service call executes
// but debugging this gets more complicated because things will likely
// occur at A before they occur at B
}
所以,Asynchronous 的总体思路是:
- 您的程序设置并开始一个服务调用,然后继续做它想做的任何其他事情,而无需等待。提示:这是开始加载动画和/或禁用某些控件的自然位置。
- 当您进行异步调用时,作为参数之一,您提供了一个在调用完成后运行的方法。
- 当服务返回结果时,将运行您指定的方法来处理结果。提示:在此方法中,您可以结束加载动画,和/或重新启用您的控件,并将结果插入您的 ViewModel。