这是我在电路板上的第一个问题。我正在使用WCF和MVVM模式编写我的第一个具有企业价值的Silverlight(5)应用程序。我的问题是我不明白如何让模型类调用WCF服务,并且(这里是问题),等待结果,然后再将它们返回到调用视图模型。
我查看了msdn是否使用了async和await关键字,但我不确定需要将哪种方法标记为“async”。在我看来,服务的自动生成的Reference.cs文件可能需要修改,但我有疑虑。更基本的是,我甚至不确定我是否需要使用异步和等待,因为我认为它应该像我期望的那样使用WCF。
无论如何,这是我的模特课。我希望在完成WCF调用之后执行return语句,但事实并非如此:
public class CRMModel
{
ObservableCollection<CarrierInfo> carrierInfoCollection = new ObservableCollection<CarrierInfo>();
public ObservableCollection<CarrierInfo> GetCarrierInformation()
{
var client = new CarrierRateService.CarrierRateServiceClient();
client.GetCarrierInformationCompleted += (s, e) =>
{
var info = e.Result;
carrierInfoCollection = info;
System.Diagnostics.Debug.WriteLine("Just got the result set: " + carrierInfoCollection.Count);
};
client.GetCarrierInformationAsync();
System.Diagnostics.Debug.WriteLine("About to return with: " + carrierInfoCollection.Count);
return carrierInfoCollection;
}
}
您可能猜到的结果是:
即将返回:0
刚刚得到结果集:3
非常感谢你的帮助! 弗朗西斯
答案 0 :(得分:3)
欢迎来到SO!
首先,要在Silverlight 5中启用async
和await
,您需要安装Microsoft.Bcl.Async package(目前处于测试阶段)。
接下来,您需要解决WCF代理生成器不生成await
兼容的异步方法这一事实。解决此问题的最简单方法是检查Visual Studio 2012添加服务引用对话框中的相应框。我不是百分之百确定这对Silverlight有用,所以如果没有,你可以use TaskCompletionSource
to create your own async
-compatible wrapper。
以下是完整的示例代码:
public static Task<ObservableCollection<CarrierInfo>> GetCarrierInformationTaskAsync(this CarrierRateService.CarrierRateServiceClient @this)
{
var tcs = new TaskCompletionSource<ObservableCollection<CarrierInfo>>();
@this.GetCarrierInformationCompleted += (s,e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
@this.GetCarrierInformationAsync(url);
return tcs.Task;
}
您现在可以使用以下代码等待它:
public ObservableCollection<CarrierInfo> GetCarrierInformation()
{
var client = new CarrierRateService.CarrierRateServiceClient();
carrierInfoCollection = await client.GetCarrierInformationTaskAsync();
System.Diagnostics.Debug.WriteLine("Just got the result set: " + carrierInfoCollection.Count);
System.Diagnostics.Debug.WriteLine("About to return with: " + carrierInfoCollection.Count);
return carrierInfoCollection;
}
答案 1 :(得分:0)
感谢您的建议,Stpehen和Toni。我一直在努力,直到我使用this article中概述的方法,其中VM将回调方法传递给模型,该模型仅使用此方法调用WCF服务。
当我最初在模型中的匿名函数中指定逻辑时,我遇到了异步的时序问题。
我来自大型机背景,所以.NET中这种简单的东西对我来说仍然是新颖的。 :)