如何对WCF异步调用异步调用

时间:2011-03-02 05:44:21

标签: c# wcf asynchronous

public class AllViewModel 
{

    private List<Settings> SettingsList;

    public ViewAgendaAllViewModel()
    {
        client.SupplierListWithSettings(GetSupplierListWithSettings_Completed)
    }

    public void GetSupplierListWithSettings_Completed(object sender, Supplier_GetListWithSettingsCompletedEventArgs e)
    {

        if (e.Error == null)
        {
            if (e.Result != null)
            {
               SettingsList = new List<Settings>(); 
                foreach (VCareSupplierDto obj in e.Result)
                {
                    SettingsList.Add(obj);

                }
            }

        }
    }
}

问题:由于异步调用,设置列表无法设置。

这是我的班级,我希望同步调用ServiceMethod SupplierListWithSettings。

当我要创建AllViewModel的实例时,它应该加载设置。

预期:当我将创建AllViewModel的实例时,它应该包含SettingList属性。

1 个答案:

答案 0 :(得分:1)

更正:SettingsList 设置,但听起来并没有按照您的意愿设置。

听起来你要求这样做:当你构造一个AllViewModel实例时,你希望在AllViewModel构造函数返回之前完全填充SettingsList属性。

虽然可以做到这一点,但有很多原因导致这可能不是一个好主意和一个可疑的设计要求。将网络调用转换为同步调用将阻止调用线程(通常是您的UI线程),只要网络请求完成,这可能需要20到30秒。您真的希望应用程序UI冻结30秒吗?您的用户可能会认为您的程序已经崩溃或“锁定”,并且会在没有意识到它没有死的情况下关闭程序。

然而,这里是如何做到的:你可以使用.NET 4.0任务并行库(TPL)使用类似的(未经测试的)将异步调用转换为同步调用:

public AllViewModel()
{
    var task = Task<List<Settings>>.Factory.StartNew(() =>
                     client.SupplierListWithSettings((s,e) => 
                     {
                         if (e.Error == null && e.Result != null)
                         {
                             var list = new List<Settings>(); 
                             foreach (VCareSupplierDto obj in e.Result)
                             {
                                 list.Add(obj);
                             }
                             task.SetResult(list);
                         }
                     }));
    this.SettingsList = task.Result;
}

同样,这不是一个好主意。对于您来说,查看代码的哪些部分假设在构造对象后立即填充SettingsList属性并更改这些依赖关系以执行类似侦听SettingsList属性的更改并执行其工作将是一个更好的练习。实际上,SettingsList实际上是异步填充的。

尝试使用异步流程而不是反对它。