注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

Silverlight开发之五异步调用队列  

2013-02-21 15:24:31|  分类: NET(C#) |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 

Silverlight开发之五异步调用队列

今天基本把异步调用队列给测试完成了,有一点儿体会,目前看来,对多个异步调用的方法有以下几种:(代码是参考陈希章的源码,此处特别鸣谢)

http://www.cnblogs.com/chenxizhang/archive/2011/08/30/2159124.html

http://www.mysjtu.com/page/M0/S795/795976.html

 

1、  最原始的,嵌套调用,在第一个异步完成的事件内调用下一个异步,依次类推。这样如果多得话,会造成代码很难看,也不容易控制。

 

            var proxy = new localhost.SampleWebServiceSoapClient();

            proxy.HelloWorldCompleted += (o, a) =>//第一个任务的回调

            {

                MessageBox.Show(a.Result);

 

                proxy.HelloWorld2Completed += (o1, a1) =>//第二个任务的回调

                {

                    MessageBox.Show(a1.Result);

 

                    proxy.HelloWorld3Completed += (o2, a2) =>

                    {

                        MessageBox.Show(a2.Result);

                    };

 

                    proxy.HelloWorld3Async();

 

                };

 

                proxy.HelloWorld2Async();

            };

 

            proxy.HelloWorldAsync();

 

2、  使用多线程来控制,这个又增加了一般人的编写难度。

3、  使用async这个异步 CTP的最新NET功能。但得安装这个补丁包或升级到更高的VS2012.

 

        async private void btAsyncCTP_Click(object sender, RoutedEventArgs e)

        {

            var proxy = new localhost.SampleWebServiceSoapClient() as localhost.SampleWebServiceSoap;

 

            var result1 = await Task<localhost.HelloWorldResponse>.Factory.FromAsync(

                proxy.BeginHelloWorld(new localhost.HelloWorldRequest(), null, null),

                proxy.EndHelloWorld);

 

            MessageBox.Show(result1.Body.HelloWorldResult);

 

            var result3 = await Task<localhost.HelloWorld3Response>.Factory.FromAsync(

                proxy.BeginHelloWorld3(new localhost.HelloWorld3Request(), null, null),

                proxy.EndHelloWorld3);

            MessageBox.Show(result3.Body.HelloWorld3Result);

 

            var result2 = await Task<localhost.HelloWorld2Response>.Factory.FromAsync(

                proxy.BeginHelloWorld2(new localhost.HelloWorld2Request(), null, null),

                proxy.EndHelloWorld2);

            MessageBox.Show(result2.Body.HelloWorld2Result);

 

        }

 

        private void btRIAService_Click(object sender, RoutedEventArgs e)

        {

            var ctx = new Web.SampleDomainContext();

            ctx.Load<Web.Employee>(ctx.GetEmployeesQuery(), result =>

            {

                MessageBox.Show(result.Entities.FirstOrDefault().FirstName);

            }, true);

 

            MessageBox.Show("加载完成");

        }

 

        async private void btAsyncCTPRIA_Click(object sender, RoutedEventArgs e)

        {

            var ctx = new Web.SampleDomainContext();

            var result = await ctx.Load<Web.Employee>(ctx.GetEmployeesQuery()).AsTask();

            MessageBox.Show(result.Entities.FirstOrDefault().FirstName);

 

 

 

            MessageBox.Show("加载完成");

        }

    public static class OperationExtensions

    {

        public static Task<T> AsTask<T>(this T operation)

          where T : OperationBase

        {

            TaskCompletionSource<T> tcs =

              new TaskCompletionSource<T>(operation.UserState);

 

            operation.Completed += (sender, e) =>

            {

                if (operation.HasError && !operation.IsErrorHandled)

                {

                    tcs.TrySetException(operation.Error);

                    operation.MarkErrorAsHandled();

                }

                else if (operation.IsCanceled)

                {

                    tcs.TrySetCanceled();

                }

                else

                {

                    tcs.TrySetResult(operation);

                }

            };

 

            return tcs.Task;

        }

    }

 

4、  使用本文的异步类,其实也类似于循环调用,不过不再是递归了。

 

            var proxy = new localhost.SampleWebServiceSoapClient();

            var task1 = new AsyncAction("task 1");

            task1.SetAction(() =>

            {

                proxy.HelloWorldCompleted += (o, a) => { MessageBox.Show(a.Result); task1.OnCompleted(); };

                proxy.HelloWorldAsync();

            });

 

            var task2 = new AsyncAction("task 2");

            task2.SetAction(() =>

            {

                proxy.HelloWorld2Completed += (o, a) => { MessageBox.Show(a.Result); task2.OnCompleted(); };

                proxy.HelloWorld2Async();

            });

 

 

            var task3 = new AsyncAction("task 3");

            task3.SetAction(() =>

            {

                proxy.HelloWorld3Completed += (o, a) => { MessageBox.Show(a.Result); task3.OnCompleted(); };

                proxy.HelloWorld3Async();

            });

 

 

            var runner = new AsyncActionRunner(task1, task3, task2);

            runner.Execute();

 

这里首先澄清一个问题,初学异步的人都会有一个疑问,异步函数的返回值有用么?这个其实很好回答,看你的情况,一般情况下,你要的实际值是不会在返回值里面的,这个最多起一个标志位的作用

真正的返回值,是在异步事件执行完成的委托或事件中的。具体到某一个应用,得看他的设计原则了。按微软的风格,一般都是在完成事件的某个参数里。

这里还有一个没引起注意的匿名委托的特点,就是其参数列表可以省略,如下:

         Button1.click += delegte{message.show(“success!”)};

正规的应该:

         Button1.click += delegte(object sender,eventargs e){message.show(“success!”)};

其中CTP的异步刚初来就学习过,却没有应用到实际的情况上,看到别人这么用,心里真得非常汗颜。

学无以用,学又有何为?

引以为鉴。

  评论这张
 
阅读(835)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017