如何正确等待WCF异步

如何正确等待WCF异步,wcf,mvvm,asynchronous,wait,async-await,Wcf,Mvvm,Asynchronous,Wait,Async Await,这是我在董事会上的第一个问题。我正在使用WCF和MVVM模式编写我的第一个企业级Silverlight(5)应用程序。我的问题是,我不知道如何让模型类调用WCF服务,并且(问题是),在将结果返回到调用视图模型之前等待结果 我查看了msdn中async和await关键字的用法,但不确定需要将哪个方法标记为“async”。在我看来,该服务自动生成的Reference.cs文件可能需要修改,但我对此表示怀疑。更基本的是,我甚至不确定我是否需要使用async和Wait,因为我假设它应该像我期望的那样通过

这是我在董事会上的第一个问题。我正在使用WCF和MVVM模式编写我的第一个企业级Silverlight(5)应用程序。我的问题是,我不知道如何让模型类调用WCF服务,并且(问题是),在将结果返回到调用视图模型之前等待结果

我查看了msdn中async和await关键字的用法,但不确定需要将哪个方法标记为“async”。在我看来,该服务自动生成的Reference.cs文件可能需要修改,但我对此表示怀疑。更基本的是,我甚至不确定我是否需要使用async和Wait,因为我假设它应该像我期望的那样通过使用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;
    }
}
公共类CRMModel
{
ObservableCollection carrierInfoCollection=新的ObservableCollection();
公共可观察收集GetCarrierInformation()
{
var client=new CarrierRateService.CarrierRateServiceClient();
client.getcarriernformationcompleted+=(s,e)=>
{
var信息=e.结果;
carrierInfoCollection=info;
System.Diagnostics.Debug.WriteLine(“刚刚得到结果集:“+carrierInfoCollection.Count”);
};
client.GetCarrierInformationAsync();
System.Diagnostics.Debug.WriteLine(“即将返回:”+carrierInfoCollection.Count);
返回载体聚焦;
}
}
正如你可能猜到的,结果是:

即将返回:0

刚刚得到结果集:3

非常感谢你的帮助! 弗朗西斯

欢迎来到SO

首先,要在Silverlight 5中启用
async
wait
,您需要安装(目前处于测试阶段)

接下来,您需要解决一个事实,即WCF代理生成器没有生成与
wait
兼容的异步方法。解决此问题的最简单方法是选中Visual Studio 2012“添加服务引用”对话框中的相应框。不过,我不能100%肯定这对Silverlight有效,所以如果不行,你可以

以下是完整的示例代码:

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;
}
公共静态任务GetCarrierInformation TaskAsync(此CarrierRateService.CarrierRateServiceClient@this)
{
var tcs=new TaskCompletionSource();
@this.getCarrierInformation已完成+=(s,e)=>
{
如果(e.Error!=null)tcs.TrySetException(e.Error);
否则,如果(如取消)tcs.TrySetCanceled();
其他tcs.TrySetResult(e.Result);
};
@此.GetCarrierInformationAsync(url);
返回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;
}
public observeCollection GetCarrierInformation()
{
var client=new CarrierRateService.CarrierRateServiceClient();
carrierInfoCollection=wait client.GetCarrierInformationTaskAsync();
System.Diagnostics.Debug.WriteLine(“刚刚得到结果集:“+carrierInfoCollection.Count”);
System.Diagnostics.Debug.WriteLine(“即将返回:”+carrierInfoCollection.Count);
返回载体聚焦;
}
欢迎来到SO

首先,要在Silverlight 5中启用
async
wait
,您需要安装(目前处于测试阶段)

接下来,您需要解决一个事实,即WCF代理生成器没有生成与
wait
兼容的异步方法。解决此问题的最简单方法是选中Visual Studio 2012“添加服务引用”对话框中的相应框。不过,我不能100%肯定这对Silverlight有效,所以如果不行,你可以

以下是完整的示例代码:

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;
}
公共静态任务GetCarrierInformation TaskAsync(此CarrierRateService.CarrierRateServiceClient@this)
{
var tcs=new TaskCompletionSource();
@this.getCarrierInformation已完成+=(s,e)=>
{
如果(e.Error!=null)tcs.TrySetException(e.Error);
否则,如果(如取消)tcs.TrySetCanceled();
其他tcs.TrySetResult(e.Result);
};
@此.GetCarrierInformationAsync(url);
返回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;
}
public observeCollection GetCarrierInformation()
{
var client=new CarrierRateService.CarrierRateServiceClient();
carrierInfoCollection=wait client.GetCarrierInformationTaskAsync();
System.Diagnostics.Debug.WriteLine(“刚刚得到结果集:“+carrierInfoCollection.Count”);
System.Diagnostics.Debug.WriteLine(“即将返回:”+carrierInfoCollection.Count);
返回载体聚焦;
}

谢谢你的建议,斯皮恩和托尼。我一直在挣扎,直到我使用了中概述的方法,VM将回调方法传递给模型,模型仅使用此方法调用WCF服务

当我最初在模型中的匿名函数中指定逻辑时,我遇到了异步的计时问题


我来自大型机背景,因此.NET中的这种简单的东西对我来说仍然是新奇的

谢谢你的建议,斯皮恩和托尼。我一直在挣扎,直到我使用了中概述的方法,VM将回调方法传递给模型,模型仅使用此方法调用WCF服务

当我最初在模型中的匿名函数中指定逻辑时,我遇到了异步的计时问题


我来自大型机背景,因此.NET中的这种简单的东西对我来说仍然是新奇的

该死,真的吗?我想我很惊讶,任何“特殊”的东西都需要让它与WCF一起工作。生成服务客户端时,该选项被禁用。哦,好吧,谢谢你的帮助…我会看看我能想出什么。PS-我应该说选项是选中的,尽管checkbo