我如何使用嵌套的异步(WCF)在Silverlight foreach循环中调用? [英] How can I use nested Async (WCF) calls within foreach loops in Silverlight?

查看:189
本文介绍了我如何使用嵌套的异步(WCF)在Silverlight foreach循环中调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下code含有一些foreach循环中的几个嵌套的异步调用。我知道的Silverlight / WCF调用asyncrously称为 - 但我怎么能保证我的wcfPhotographers,wcfCategories和wcfCategories对象是准备foreach循环开始之前?我敢肯定,我会这一切错误的方式 - 和将AP preciate的帮助,你可以给。

 私人无效PopulateControl()
    {        清单< CustomPhotographer> PhotographerList =新的List< CustomPhotographer>();        proxy.GetPhotographerNamesCompleted + = proxy_GetPhotographerNamesCompleted;
        proxy.GetPhotographerNamesAsync();
        //为每个摄影师
        的foreach(在wcfPhotographers VAR eachPhotographer)
        {            CustomPhotographer thisPhotographer =新CustomPhotographer();            thisPhotographer.PhotographerName = eachPhotographer.ContactName;
            thisPhotographer.PhotographerId = eachPhotographer.PhotographerID;            thisPhotographer.Categories =新的List< CustomCategory>();            proxy.GetCategoryNamesFilteredByPhotographerCompleted + = proxy_GetCategoryNamesFilteredByPhotographerCompleted;
            proxy.GetCategoryNamesFilteredByPhotographerAsync(thisPhotographer.PhotographerId);
            //每个类别
            的foreach(在wcfCategories VAR eachCatergory)
            {                CustomCategory thisCategory =新CustomCategory();                thisCategory.CategoryName = eachCatergory.CategoryName;
                thisCategory.CategoryId = eachCatergory.CategoryID;                thisCategory.SubCategories =新的List< CustomSubCategory>();                proxy.GetSubCategoryNamesFilteredByCategoryCompleted + = proxy_GetSubCategoryNamesFilteredByCategoryCompleted;
                proxy.GetSubCategoryNamesFilteredByCategoryAsync(thisPhotographer.PhotographerId,thisCategory.CategoryId);                //为每个子类别
                的foreach(在wcfSubCategories VAR eachSubCatergory)
                {
                    CustomSubCategory thisSubCatergory =新CustomSubCategory();                    thisSubCatergory.SubCategoryName = eachSubCatergory.SubCategoryName;
                    thisSubCatergory.SubCategoryId = eachSubCatergory.SubCategoryID;
                }
                thisPhotographer.Categories.Add(thisCategory);
            }            PhotographerList.Add(thisPhotographer);
        }        PhotographerNames.ItemsSource = PhotographerList;
    }
    无效proxy_GetPhotographerNamesCompleted(对象发件人,GetPhotographerNamesCompletedEventArgs E)
    {
        wcfPhotographers = e.Result.ToList();
    }
    无效proxy_GetCategoryNamesFilteredByPhotographerCompleted(对象发件人,GetCategoryNamesFilteredByPhotographerCompletedEventArgs E)
    {
        wcfCategories = e.Result.ToList();
    }    无效proxy_GetSubCategoryNamesFilteredByCategoryCompleted(对象发件人,GetSubCategoryNamesFilteredByCategoryCompletedEventArgs E)
    {
        wcfSubCategories = e.Result.ToList();
    }


解决方案

是的,然后才能与算法的继续执行下一步,你需要已经得到了previous一步,它可以是坚硬的结果当你使用异​​步方法。

如果这不是在UI线程上发生的事情,那么你可以只阻止和等待响应。例如,已分别已完成的方法信号(使用任何同步原语都可以在Silverlight,我不知道随便例如,如果ManualResetEvent的是存在的,如果是这样,有完成回调调用。设置() ),然后让你的主PopulateControl方法调用FooAsync()调用,然后阻塞,直到ManualResetEvent的信号(通过调用 .Wait()

如果这是在UI线程上,你真的需要写一个非阻塞的解决方案,那么它是非常非常难code这个正确的C#。您可以考虑使用F#代替,其中异步取值为非阻塞调用一个不错的编程模型。

编辑:

伪code为例来阻止的结果:

  //类级别
ManualResetEvent的MRE =新的ManualResetEvent(假);
//一些需要作出WCF调用和使用方法结果
无效布拉赫(){
    //脚本非常重要
    proxy.FooCompleted + =(0,EA)=> {... mre.Set(); };
    proxy.FooAsync(...);
    mre.WaitOne(); //阻塞,直到FooCompleted
    //从FooCompleted使用效果,现在他们在这里
    // mre.Reset(),如果你打算以后再次使用
}

我用FooCompleted的lambda,但使用一个单独的方法好像你已经是没关系。

The following code contains a few nested async calls within some foreach loops. I know the silverlight/wcf calls are called asyncrously -but how can I ensure that my wcfPhotographers, wcfCategories and wcfCategories objects are ready before the foreach loop start? I'm sure I am going about this all the wrong way -and would appreciate an help you could give.

    private void PopulateControl()
    {

        List<CustomPhotographer> PhotographerList = new List<CustomPhotographer>();

        proxy.GetPhotographerNamesCompleted += proxy_GetPhotographerNamesCompleted;
        proxy.GetPhotographerNamesAsync();


        //for each photographer
        foreach (var eachPhotographer in wcfPhotographers)
        {

            CustomPhotographer thisPhotographer = new CustomPhotographer();

            thisPhotographer.PhotographerName = eachPhotographer.ContactName;
            thisPhotographer.PhotographerId = eachPhotographer.PhotographerID;

            thisPhotographer.Categories = new List<CustomCategory>();

            proxy.GetCategoryNamesFilteredByPhotographerCompleted += proxy_GetCategoryNamesFilteredByPhotographerCompleted;
            proxy.GetCategoryNamesFilteredByPhotographerAsync(thisPhotographer.PhotographerId);


            // for each category
            foreach (var eachCatergory in wcfCategories)
            {

                CustomCategory thisCategory = new CustomCategory();

                thisCategory.CategoryName = eachCatergory.CategoryName;
                thisCategory.CategoryId = eachCatergory.CategoryID;

                thisCategory.SubCategories = new List<CustomSubCategory>();

                proxy.GetSubCategoryNamesFilteredByCategoryCompleted += proxy_GetSubCategoryNamesFilteredByCategoryCompleted;
                proxy.GetSubCategoryNamesFilteredByCategoryAsync(thisPhotographer.PhotographerId,thisCategory.CategoryId);

                // for each subcategory
                foreach(var eachSubCatergory in wcfSubCategories)
                {
                    CustomSubCategory thisSubCatergory = new CustomSubCategory();

                    thisSubCatergory.SubCategoryName = eachSubCatergory.SubCategoryName;
                    thisSubCatergory.SubCategoryId = eachSubCatergory.SubCategoryID;
                }


                thisPhotographer.Categories.Add(thisCategory);
            }

            PhotographerList.Add(thisPhotographer);
        }

        PhotographerNames.ItemsSource = PhotographerList;
    }




    void proxy_GetPhotographerNamesCompleted(object sender, GetPhotographerNamesCompletedEventArgs e)
    {
        wcfPhotographers = e.Result.ToList();
    }


    void proxy_GetCategoryNamesFilteredByPhotographerCompleted(object sender, GetCategoryNamesFilteredByPhotographerCompletedEventArgs e)
    {
        wcfCategories = e.Result.ToList();
    }

    void proxy_GetSubCategoryNamesFilteredByCategoryCompleted(object sender, GetSubCategoryNamesFilteredByCategoryCompletedEventArgs e)
    {
        wcfSubCategories = e.Result.ToList();
    }

解决方案

Yes, before you can proceed with the next step of the algorithm, you need to have gotten the result of the previous step, which can be hard when you have to use the async methods.

If this is not happening on the UI thread, then you could just block and wait for the response. For example, have each "completed" method signal (using whatever synchronization primitives are available in Silverlight; I don't know offhand e.g. if ManualResetEvent is there, if so, have the completed callback call .Set()), and then have your main PopulateControl method invoke the FooAsync() call and then block until the ManualResetEvent signals (by calling .Wait()).

If this is on the UI thread and you really need to write a non-blocking solution, then it is much, much harder to code this up correctly in C#. You might consider using F# instead, where asyncs provide a nice programming model for non-blocking calls.

EDIT:

Pseudo-code example to block for results:

// class-level
ManualResetEvent mre = new ManualResetEvent(false);
// some method that needs to make WCF call and use results
void Blah() {
    // yadda yadda
    proxy.FooCompleted += (o,ea) => { ... mre.Set(); };
    proxy.FooAsync(...);
    mre.WaitOne();  // block until FooCompleted
    // use results from FooCompleted now that they're here
    // mre.Reset() if you intend to use it again later
}

I used a lambda for FooCompleted, but using a separate method like you have is fine too.

这篇关于我如何使用嵌套的异步(WCF)在Silverlight foreach循环中调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆