http://www.csframework.com/archive/5/arc-5-20110612-1593.htm
C# WebService异步处理/异步调用详解(附实例源代码)
有时WebService后台程序在运算复杂的数据时客户界面呈现等候状态, 在有些情况下客户不愿意等候也不关心运算何时结束。从设计角度来看至少可使用两种方法解决:1.多线程 2.Web方法异步调用
本文重心是WebService技术,所以讲解Web方法异步调用吧!
先看后台代码,Web方法定义,注意标明 [WebMethod]的方法.
代码相当简单,只定义了3个返回数据的方法.
public
class Service : System.Web.Services.WebService
{
public Service()
{
}
[WebMethod]
public
byte[] GetUserList()
{
return
new UserData().GetUserList();
}
[WebMethod]
public
byte[] AnsyTest1()
{
return
new UserData().AnsyProcess1();
}
[WebMethod]
public
byte[] AnsyTest2()
{
return
new UserData().AnsyProcess2();
}
从UserData类获取数据
public
class UserData
{
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-测试员");
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");
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()
{
Thread.Sleep(10 * 1000);
return GetUserList();
}
public
byte[] AnsyProcess2()
{
Thread.Sleep(30 * 1000);
return GetWebSite();
}
}
后台准备就绪,按F5运行,Service.asmx内容.
从上图看出Service.asmx暴露了3个Web方法. (从客户端调用这些方法)
客户端添加Web Refernces, 命名为UserWebService,引用完成后自动生成Service类.
类结构图1
类结构2
客户端建立测试环境,测试窗体
异步调用测试类
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();
}
}
TaskManager任务管理器类
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;
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;
}
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));
return dt;
}
public
void AsyncAnalysisAttendStep1()
{
AddTask("异步处理1进程");
_webService.AnsyTest1Async();
_webService.AnsyTest1Completed +=
new AnsyTest1CompletedEventHandler(OnStep1Completed);
}
public
void AsyncAnalysisAttendStep2()
{
AddTask("异步处理2进程");
_webService.AnsyTest2Async();
_webService.AnsyTest2Completed +=
new AnsyTest2CompletedEventHandler(OnStep2Completed);
}
void OnStep1Completed(
object sender, AnsyTest1CompletedEventArgs e)
{
CallCompletedMethod(e.Result, e.Error);
}
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();
}
}
好了,运行客户端点击[调用WebService方法(异步处理)任务1]按钮,等待10秒后...
点击[调用WebService方法(异步处理)任务2]按钮,等待30秒...
测试完成,结果显示: