Silverlight实现调用多个异步任务

这是一个常见的问题,由于Silverlight只支持异步调用后台的服务,而如果有多个任务的话,可能就很麻烦,往往就是要在一个异步任务结束事件中去调用另外一个任务,以此类推。典型的问题就是,代码很复杂,而且几乎很难维护。看看下面的代码吧

            //传统的多个异步任务的调用方法,必须是一层一层嵌套的方式
           
            var proxy = new ServiceReference1.WebService1SoapClient();
            proxy.Endpoint.Address = new System.ServiceModel.EndpointAddress(
                new Uri(App.Current.Host.Source, "../WebService1.asmx"));

            proxy.HelloWorldCompleted += (o, a) =>
            {
               
                proxy.GetEmployeeCompleted += (o1, a1) =>
                {
                    proxy.GetCustomersCompleted += (o2, a1) =>
                    {

                    };
                    proxy.GetCustomersAsync();
                };

                proxy.GetEmployeeAsync();
            };
            proxy.HelloWorldAsync();


这篇文章提供了一个不错的思路。这篇文章的评论中,有朋友也提到了Reactive Framework,我看了看,还没有找到很好的应用方法。这个Framework是一个很强大的东西,但在本文讨论的场景中具体该如何应用,如果有这方面研究的朋友,请不吝赐教
在这篇文章提供的简单模型基础上,我做了一些修改,并且也增加了一些更加实用的特性。共享出来给大家参考

 
添加和改进的功能主要是:

1.使用更加便捷(原先是用IEnumerator去构造Runner,现在提供了更多的支持,可以是一个Array,也可以是一个List等等,因为我们很多时候任务是动态构造出来的)

2.提供了任务结果反馈(ActionResult)的功能

3.提供了任务之间约束的功能,在每个任务里面都可以得到前置任务的信息

完整源代码

如果你不想下载包,可以直接复制这个代码进行使用或者修改

 

using System;
using System.Collections.Generic;
/*
 * 这个设计针对在Silverlight中经常需要对多个远程服务进行调用,而且我们可能需要让这些任务之间有固定的顺序,同时还希望能够在任务之间传递任务状态。
 * 作者:陈希章
 * 时间:2011年8月30日
 * 反馈:ares@xizhang.com
 */

#region Sample Code
        第一个任务
        //var task = new AsyncAction();
        //task.SetAction(() =>
        //{
        //    var proxy = new ServiceReference1.WebService1SoapClient();
        //    proxy.Endpoint.Address = new System.ServiceModel.EndpointAddress(
        //        new Uri(App.Current.Host.Source, "../WebService1.asmx"));

        //    proxy.HelloWorldCompleted += (o, a) =>
        //    {
        //        task.ActionResult.TaskName = "Hello,world";
        //        task.ActionResult.Message = "Test test";
        //        task.ActionResult.Result = a.Result;
        //        task.ActionResult.Status = ActionStatus.Success;
        //        task.OnCompleted();
        //    };

        //    proxy.HelloWorldAsync();
        //}, true);

        第二个任务
        //var task2 = new AsyncAction();
        //task2.SetAction(() =>
        //{
        //    var proxy = new ServiceReference1.WebService1SoapClient();
        //    proxy.Endpoint.Address = new System.ServiceModel.EndpointAddress(
        //        new Uri(App.Current.Host.Source, "../WebService1.asmx"));

        //    proxy.HelloWorldCompleted += (o, a) =>
        //    {
        //        task2.ActionResult.TaskName = "Hello,world";
        //        task2.ActionResult.Message = "Test test";
        //        task2.ActionResult.Result = a.Result;
        //        task2.ActionResult.Status = ActionStatus.Success;
        //        task2.OnCompleted();
        //    };
        //    proxy.HelloWorldAsync();
        //}, true);

        构造Runner
        //var runner = new AsyncActionRunner(new[] { task, task2 });

        注册完成事件
        //runner.Completed += (o, a) =>
        //{
        //    //将界面设置为空闲
        //    busyIndicator.IsBusy = false;
        //    //显示所有任务的执行结果
        //    dgResult.ItemsSource = runner.TaskResults;
        //};
        将界面设置为忙碌
        //busyIndicator.IsBusy = true;

        执行
        //runner.Execute();
#endregion


namespace System
{
    /// <summary>
    /// 这个枚举记录了任务的状态,默认为Ready
    /// </summary>
    public enum ActionStatus
    {
        Ready,//准备好,如果最后检查仍然为这个状态,则通常表示该任务被跳过了
        Success,//成功
        Failure,//失败
        Completed//完成
    }
    /// <summary>
    /// 这个记录了任务的结果
    /// </summary>
    public class ActionResult
    {
        public ActionResult()
        {
            Status = ActionStatus.Ready;//默认为ready
            StartTime = DateTime.Now;
        }
        /// <summary>
        /// 任务名称
        /// </summary>
        public string TaskName { get; set; }
        /// <summary>
        /// 状态
        /// </summary>
        public ActionStatus Status { get; set; }
        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }
        /// <summary>
        /// 任务结果
        /// </summary>
        public object Result { get; set; }

        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime StartTime { get; set; }
        /// <summary>
        /// 结束时间
        /// </summary>Jquery的appendTo和after区别和应用
        public DateTime EndTime { get; set; }
    }
    /// <summary>
    /// 异步任务的接口
    /// </summary>
    public interface IAsyncAction
    {
        void Execute();
        event EventHandler Completed;
        ActionResult PreActionResult { get; set; }
        ActionResult ActionResult { get; set; }
    }
    /// <summary>
    /// 异步任务的实现类型
    /// </summary>
    public class AsyncAction : IAsyncAction
    {
        public AsyncAction()
        {
            ActionResult = new ActionResult();
        }

        private bool AutoComplete = false;
        private Action Action { get; set; }
        /// <summary>
        /// 设置要执行的操作
        /// </summary>
        /// <param name="action">操作</param>
        /// <param name="autoComplete">是否自动完成</param>
        public void SetAction(Action action, bool autoComplete)
        {
            Action = action;
            AutoComplete = autoComplete;
        }


        public virtual void Execute()
        {
            if(Action != null)
            {
                ActionResult.StartTime = DateTime.Now;
                Action();
                if(!AutoComplete)
                    OnCompleted();
            }
        }

        public event EventHandler Completed;
        public void OnCompleted()
        {
            var completed = this.Completed;
            if(completed != null)
            {
                completed(this, EventArgs.Empty);
            }
        }
        /// <summary>
        /// 前置任务的结果,添加这个功能目的是,可能多个任务之间互相有所依赖,例如某个任务要根据前面任务的情况决定是否执行
        /// </summary>
        public ActionResult PreActionResult { get; set; }
        /// <summary>
        /// 当前任务的结果
        /// </summary>
        public ActionResult ActionResult { get; set; }
    }


    /// <summary>
    /// 任务运行器
    /// </summary>
    public class AsyncActionRunner
    {

        public AsyncActionRunner()
        {
            TaskResults = new List<ActionResult>();
        }

        private readonly IEnumerator<IAsyncAction> _enumerator;
        public AsyncActionRunner(IEnumerator<IAsyncAction> enumerator)
            : this()
        {
            this._enumerator = enumerator;
        }

        public AsyncActionRunner(IEnumerable<IAsyncAction> tasks)
            : this()
        {
            _enumerator = tasks.GetEnumerator();
        }

        /// <summary>
        /// 完成事件及处理方法
        /// </summary>
        public event EventHandler Completed;
        /// <summary>
        /// 保存所有任务的执行结果
        /// </summary>
        public List<ActionResult> TaskResults { get; private set; }
        /// <summary>
        /// 临时保存的当前任务的执行结果
        /// </summary>
        private ActionResult tmp = null;
        /// <summary>
        /// 执行所有任务
        /// </summary>
        public void Execute()
        {
            if(this._enumerator.MoveNext())
            {
                this._enumerator.Current.Completed += (sender, args) =>
                {
                    tmp = ((IAsyncAction)sender).ActionResult;
                    tmp.EndTime = DateTime.Now;
                    TaskResults.Add(tmp);
                    this.Execute();
                };
                this._enumerator.Current.PreActionResult = tmp;
                this._enumerator.Current.Execute();
            }Android 得到地理位置并分析出具体城市
            else
            {
                var completed = this.Completed;
                if(completed != null)
                {
                    completed(this, EventArgs.Empty);
                }
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值