C# WebService异步处理/异步调用详解
C# WebService异步处理/异步调用详解
C# WebService异步处理/异步调用详解(附实例源代码)
有时WebService后台程序在运算复杂的数据时客户界面呈现等候状态, 在有些情况下客户不愿意等候也不关心运算何时结束。从设计角度来看至少可使用两种方法解决:1.多线程 2.Web方法异步调用 public class Service : System.Web.Services.WebService
{ public Service() { // } //建立一个自己的Web方法 [WebMethod] public byte[] GetUserList() { //返回用户列表 return new UserData().GetUserList(); } [WebMethod] public byte[] AnsyTest1() { //Web方法,从数据访问层获取计算过的数据 return new UserData().AnsyProcess1(); } [WebMethod] public byte[] AnsyTest2() { //Web方法,从数据访问层获取计算过的数据 return new UserData().AnsyProcess2(); } 从UserData类获取数据 public class UserData
{ //数据访问层 //获取用户列表,这里方便演示直接创建一个DataTable.(您可以从SqlServer获取数据) public byte[] GetUserList() { DataSet ds = new DataSet(); DataTable dt = new DataTable(); dt.Columns.Add("UserName", typeof(string)); ds.Tables.Add(dt); this.AddRow(dt, "admini-系统管理员"); this.AddRow(dt, "test-测试员"); //将DataSet转换为byte数组,用于Http传输。 return ZipObject.CompressionDataSet(ds); } //返回网站列表 public byte[] GetWebSite() { DataSet ds = new DataSet(); DataTable dt = new DataTable(); dt.Columns.Add("WebName", typeof(string)); ds.Tables.Add(dt); this.AddRow(dt, "C#易学网-www.vjsdn.com"); this.AddRow(dt, "C#易学论坛-www.vjsdn.com"); //将DataSet转换为byte数组,用于Http传输。 return ZipObject.CompressionDataSet(ds); } private void AddRow(DataTable dt, string value) { //增加一条记录 DataRow row = dt.NewRow(); row[0] = value; dt.Rows.Add(row); } public byte[] AnsyProcess1() { //假设这里执行一个复杂的运算,需要用时10秒以上 Thread.Sleep(10 * 1000);//等待10秒 //运算完成,返回一个数据集 return GetUserList(); } public byte[] AnsyProcess2() { //假设这里执行一个复杂的运算,需要用时30秒以上 Thread.Sleep(30 * 1000);//等待30秒 //运算完成,返回一个数据集 return GetWebSite(); } }
从上图看出Service.asmx暴露了3个Web方法. (从客户端调用这些方法) 客户端添加Web Refernces, 命名为UserWebService,引用完成后自动生成Service类.
//测试类
public class WebServiceTester { public void Test1(DataGridView taskView, DataGridView resultView) { new TaskManager(taskView, resultView, "异步处理1进程").AsyncAnalysisAttendStep1(); } public void Test2(DataGridView view, DataGridView resultView) { new TaskManager(view, resultView, "异步处理2进程").AsyncAnalysisAttendStep2(); } }
/// <summary>
/// 任务管理器 /// </summary> public class TaskManager { private static int TaskIDSequence = 0; //所有任务序号 private Service _webService = null; private DataTable _TaskData = null; //任务列表数据 private DataGridView _TaskView = null;//任务列表表格显示 private DataGridView _ResultView = null; //显示运算结果 private string _TaskName = string.Empty; private int _TaskID = 0; /// <summary> /// 构造器.参数说明 taskview:异步处理任务显示界面 taskName:任务名称 /// </summary> public TaskManager(DataGridView taskview, DataGridView resultView, string taskName) { //增加任务序号 TaskManager.TaskIDSequence += 1; _TaskID = TaskManager.TaskIDSequence; _TaskView = taskview; _TaskName = taskName; _ResultView = resultView; _webService = new Service(); if (taskview.DataSource == null) { _TaskData = TaskManager.CreateTaskTable(); taskview.DataSource = _TaskData; } else _TaskData = taskview.DataSource as DataTable; } /// <summary> /// 创建任务数据表结构 /// </summary> public static DataTable CreateTaskTable() { DataTable dt = new DataTable(); dt.Columns.Add("TaskID", typeof(int)); dt.Columns.Add("TaskName", typeof(string)); dt.Columns.Add("Content", typeof(string)); //任务内容 dt.Columns.Add("FromTime", typeof(DateTime));//任务开始时间 dt.Columns.Add("ToTime", typeof(DateTime));//结束时间 dt.Columns.Add("Status", typeof(string));//处理状态 dt.Columns.Add("TimeUsed", typeof(string)); //处理结束使用时间秒(s) return dt; } //异步处理1 public void AsyncAnalysisAttendStep1() { AddTask("异步处理1进程"); _webService.AnsyTest1Async(); //调用AnsyTest1方法的异步方法.尾部是Async的方法。 _webService.AnsyTest1Completed += new AnsyTest1CompletedEventHandler(OnStep1Completed); } //异步处理2 public void AsyncAnalysisAttendStep2() { AddTask("异步处理2进程"); //调用AnsyTest2方法的异步方法.尾部是Async的方法。 _webService.AnsyTest2Async(); _webService.AnsyTest2Completed += new AnsyTest2CompletedEventHandler(OnStep2Completed); } //异步处理1结束时触发的事件 void OnStep1Completed(object sender, AnsyTest1CompletedEventArgs e) { CallCompletedMethod(e.Result, e.Error); } //异步处理2结束时触发的事件 void OnStep2Completed(object sender, AnsyTest2CompletedEventArgs e) { CallCompletedMethod(e.Result, e.Error); } private void CallCompletedMethod(byte[] result, Exception exception) { //异步处理完成,且处理成功 if (exception == null) { if (result != null) //异步处理返回的数据 { DataSet ds = ZipObject.DecompressionDataSet(result); _ResultView.DataSource = ds.Tables[0]; } UpdateTaskStatus("处理完成."); string msg = "任务编号:" + _TaskID.ToString() + " 名称:" + _TaskName + "\n处理完成!"; MessageBox.Show(msg); } else { UpdateTaskStatus("发生错误."); string msg = "任务编号:" + _TaskID.ToString() + " 名称:" + _TaskName + "\n处理时发生错误!\n\n 错误摘要:\n"; msg = msg + exception.Message; MessageBox.Show(msg); } } //更新处理状态 private void UpdateTaskStatus(string status) { DataRow[] task = _TaskData.Select("TaskID=" + _TaskID.ToString()); if (task != null && task.Length > 0) { DateTime from = DateTime.Parse(task[0]["FromTime"].ToString()); TimeSpan span = DateTime.Now - from; int timeused = Convert.ToInt16(span.TotalSeconds); task[0]["Status"] = status; task[0]["ToTime"] = DateTime.Now; task[0]["TimeUsed"] = timeused.ToString() + "s"; _TaskData.AcceptChanges(); _TaskView.Refresh(); } } //增加一个任务 private void AddTask(string content) { DataRow row = _TaskData.NewRow(); row["TaskID"] = _TaskID; row["TaskName"] = _TaskName; row["Content"] = content; row["FromTime"] = DateTime.Now; row["Status"] = "处理中..."; _TaskData.Rows.Add(row); _TaskData.AcceptChanges(); _TaskView.Refresh(); } }
参考文档:
C#-C/S框架-WebService部署图 C#多线程处理多个队列的数据(交叉线程访问及Invoke方法使用) Delphi程序调用C#.Net编译的DLL并打开窗体(详解) C# 动态编译及调用WebService的方法 C#.Net WCF实例详解及源码下载 C#调用C++编译的DLL详解 C# WebService代理类详解 CSFramework.WebApi时钟定时作业异步处理程序(IThreadHandler接口)实现 C#异步操作等待窗体,异步多线程处理数据通用界面(frmThreadOperating) C#多线程异步处理数据通用界面窗体(frmThreadOperating) C# Dev GridView表格的CustomUnboundColumnData事件异步加载图片类AsynDownImage C# 调用Process.Start 请求的操作需要提升解决方案 C# FastReport.NET批量打印条形码报表详解教程 Winform三层架构+WebService+权限管理系统软件开发平台(C#.NET开发) C# TextReader / TextWriter基类详解
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 | |