提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2011-08-30 15:25:13.000|阅读 507 次
概述:本文主要讲述一下在Silverlight中对多个异步任务的调用问题,希望对大家有帮助。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
这是一个常见的问题,由于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();
为了解决这个问题,我自己也想过一些办法,同时参考了张志敏的如下文章
//www.cnblogs.com/beginor/archive/2010/12/24/1915910.html
这篇文章提供了一个不错的思路。这篇文章的评论中,有朋友也提到了Reactive Framework,我看了看,还没有找到很好的应用方法。这个Framework是一个很强大的东西,但在本文讨论的场景中具体该如何应用,如果有这方面研究的朋友,请不吝赐教
在这篇文章提供的简单模型基础上,我做了一些修改,并且也增加了一些更加实用的特性。共享出来给大家参考
添加和改进的功能主要是:
1.使用更加便捷(原先是用IEnumerator去构造Runner,现在提供了更多的支持,可以是一个Array,也可以是一个List等等,因为我们很多时候任务是动态构造出来的)
2.提供了任务结果反馈(ActionResult)的功能
3.提供了任务之间约束的功能,在每个任务里面都可以得到前置任务的信息
如何使用?
第一步:添加Nuget Package,关于什么是Nuget,请参考 //www.cnblogs.com/dudu/archive/2011/07/15/nuget.html
第二步,参考如下的范例代码
运行效果
完整源代码
如果你不想下载包,可以直接复制这个代码进行使用或者修改
using System;
using System.Collections.Generic;
using System.Linq;
/*
* 这个设计针对在Silverlight中经常需要对多个远程服务进行调用,而且我们可能需要让这些任务之间有固定的顺序,同时还希望能够在任务之间传递任务状态,还支持进度汇报的功能
* 作者:陈希章
* 时间:2011年8月30日
* 反馈:ares@xizhang.com
*/
#region Sample Code
////第一个任务
//var task = new AsyncAction("Task 1");
//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.Message = "Test test";
// task.ActionResult.Result = a.Result;
// task.ActionResult.Status = ActionStatus.Success;
// task.OnCompleted();
// };
// proxy.HelloWorldAsync();
//}, true);
////第二个任务
//var task2 = new AsyncAction("Task 2");
//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.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;
//};
//runner.ProgressChanged += (o, a) =>
//{
// busyIndicator.BusyContent =
string.Format("Current Step :{0},
Percent:{1:p}, Name:{2},Status:{3}", a.Current, a.Percent,
a.ActionResult.TaskName, a.ActionResult.Status);
//};
////将界面设置为忙碌
//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>
public DateTime EndTime { get; set; }
}
/// <summary>
/// 异步任务的接口
/// </summary>
public interface IAsyncAction
{
void Execute();
event EventHandler Completed;
ActionResult PreActionResult { get; set; }
ActionResult ActionResult { get; set; }
string TaskName { get; set; }
}
/// <summary>
/// 异步任务的实现类型
/// </summary>
public class AsyncAction : IAsyncAction
{
public AsyncAction(string name):this()
{
TaskName = name;
}
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>
private string taskName = string.Empty;
public string TaskName
{
get
{
return taskName;
}
set
{
taskName = value; ActionResult.TaskName = value;
}
}
}
/// <summary>
/// 任务运行器
/// </summary>
public class AsyncActionRunner
{
public AsyncActionRunner()
{
TaskResults = new List<ActionResult>();
}
private readonly IEnumerator<IAsyncAction> _enumerator;
private int taskCount = 0;
//public AsyncActionRunner(IEnumerator<IAsyncAction> enumerator)
// : this()
//{
// this._enumerator = enumerator;
//}
public AsyncActionRunner(IList<IAsyncAction> tasks)
: this()
{
taskCount = tasks.Count();
_enumerator = tasks.GetEnumerator();
}
/// <summary>
/// 完成事件及处理方法
/// </summary>
public event EventHandler Completed;
/// <summary>
/// 进度发生更改时发生
/// </summary>
public event EventHandler<ProgressEventArgs> ProgressChanged;
/// <summary>
/// 保存所有任务的执行结果
/// </summary>
public List<ActionResult> TaskResults { get; private set; }
/// <summary>
/// 临时保存的当前任务的执行结果
/// </summary>
private ActionResult tmp = null;
private int index = 1;
/// <summary>
/// 执行所有任务
/// </summary>
public void Execute()
{
if(this._enumerator.MoveNext())
{
var current = this._enumerator.Current;
tmp = current.ActionResult;
var ci = index++;
current.Completed += (sender, args) =>
{
tmp = ((IAsyncAction)sender).ActionResult;
tmp.EndTime = DateTime.Now;
TaskResults.Add(tmp);
if(ProgressChanged != null)
{
ProgressChanged(this, new ProgressEventArgs(ci,
(double)ci / taskCount, tmp));
}
this.Execute();
};
current.PreActionResult = tmp;
current.Execute();
ProgressChanged(this, new ProgressEventArgs
(ci, (double)ci / taskCount, tmp));
}
else
{
index = 1;//将进度复位
var completed = this.Completed;
if(completed != null)
{
completed(this, EventArgs.Empty);
}
}
}
}
/// <summary>
/// 进度事件的参数
/// </summary>
public class ProgressEventArgs : EventArgs
{
public int Current { get; set; }
public ActionResult ActionResult { get; set; }
public ProgressEventArgs(int current, double percent, ActionResult result)
{
this.Current = current;
ActionResult = result;
Percent = percent;
}
public double Percent { get; set; }
}
}
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:博客园面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢