基于事件的异步编程和Web服务
来源:互联网 发布:快乐码字软件 编辑:程序博客网 时间:2024/04/25 06:47
2using System.Web;
3using System.Web.Services;
4using System.Web.Services.Protocols;
5
6[WebService(Namespace = "http://tempuri.org/")]
7[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
8public class Service : System.Web.Services.WebService
9{
10 public Service () {
12 //Uncomment the following line if using designed components
13 //InitializeComponent();
14 }
15
16 [WebMethod]
17 public string HelloWorld() {
18 return "Hello World";
19 }
20
21 [WebMethod]
22 public int GetInt()
23 {
24 return 1;
25 }
26}
这个类应该是运行在另外一台机器上的,一般用做数据库的操作等方面。
在客户端,我们可以用WSDL工具或微软的IDE给一个Project添加Web引用,不给出具体的操作。
添加好之后,我们看看生成的本地代理类。
2// <auto-generated>
3// This code was generated by a tool.
4// Runtime Version:2.0.50727.42
5//
6// Changes to this file may cause incorrect behavior and will be lost if
7// the code is regenerated.
8// </auto-generated>
9//------------------------------------------------------------------------------
10
11//
12// This source code was auto-generated by Microsoft.VSDesigner, Version 2.0.50727.42.
13//
14#pragma warning disable 1591
15
16namespace CourtMediaUI.TestService {
17 using System.Diagnostics;
18 using System.Web.Services;
19 using System.ComponentModel;
20 using System.Web.Services.Protocols;
21 using System;
22 using System.Xml.Serialization;
23
24
25 /**//// <remarks/>
26 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.42")]
27 [System.Diagnostics.DebuggerStepThroughAttribute()]
28 [System.ComponentModel.DesignerCategoryAttribute("code")]
29 [System.Web.Services.WebServiceBindingAttribute(Name="ServiceSoap", Namespace="http://tempuri.org/")]
30 public partial class Service : System.Web.Services.Protocols.SoapHttpClientProtocol {
31
32 private System.Threading.SendOrPostCallback HelloWorldOperationCompleted;
33
34 private System.Threading.SendOrPostCallback GetIntOperationCompleted;
35
36 private bool useDefaultCredentialsSetExplicitly;
37
38 /**//// <remarks/>
39 public Service() {
40 this.Url = global::CourtMediaUI.Properties.Settings.Default.CourtMediaUI_TestService_Service;
41 if ((this.IsLocalFileSystemWebService(this.Url) == true)) {
42 this.UseDefaultCredentials = true;
43 this.useDefaultCredentialsSetExplicitly = false;
44 }
45 else {
46 this.useDefaultCredentialsSetExplicitly = true;
47 }
48 }
49
50 public new string Url {
51 get {
52 return base.Url;
53 }
54 set {
55 if ((((this.IsLocalFileSystemWebService(base.Url) == true)
56 && (this.useDefaultCredentialsSetExplicitly == false))
57 && (this.IsLocalFileSystemWebService(value) == false))) {
58 base.UseDefaultCredentials = false;
59 }
60 base.Url = value;
61 }
62 }
63
64 public new bool UseDefaultCredentials {
65 get {
66 return base.UseDefaultCredentials;
67 }
68 set {
69 base.UseDefaultCredentials = value;
70 this.useDefaultCredentialsSetExplicitly = true;
71 }
72 }
73
74 /**//// <remarks/>
75 public event HelloWorldCompletedEventHandler HelloWorldCompleted;
76
77 /**//// <remarks/>
78 public event GetIntCompletedEventHandler GetIntCompleted;
79
80 /**//// <remarks/>
81 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
82 public string HelloWorld() {
83 object[] results = this.Invoke("HelloWorld", new object[0]);
84 return ((string)(results[0]));
85 }
86
87 /**//// <remarks/>
88 public void HelloWorldAsync() {
89 this.HelloWorldAsync(null);
90 }
91
92 /**//// <remarks/>
93 public void HelloWorldAsync(object userState) {
94 if ((this.HelloWorldOperationCompleted == null)) {
95 this.HelloWorldOperationCompleted = new System.Threading.SendOrPostCallback(this.OnHelloWorldOperationCompleted);
96 }
97 this.InvokeAsync("HelloWorld", new object[0], this.HelloWorldOperationCompleted, userState);
98 }
99
100 private void OnHelloWorldOperationCompleted(object arg) {
101 if ((this.HelloWorldCompleted != null)) {
102 System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
103 this.HelloWorldCompleted(this, new HelloWorldCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
104 }
105 }
106
107 /**//// <remarks/>
108 [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/GetInt", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
109 public int GetInt() {
110 object[] results = this.Invoke("GetInt", new object[0]);
111 return ((int)(results[0]));
112 }
113
114 /**//// <remarks/>
115 public void GetIntAsync() {
116 this.GetIntAsync(null);
117 }
118
119 /**//// <remarks/>
120 public void GetIntAsync(object userState) {
121 if ((this.GetIntOperationCompleted == null)) {
122 this.GetIntOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetIntOperationCompleted);
123 }
124 this.InvokeAsync("GetInt", new object[0], this.GetIntOperationCompleted, userState);
125 }
126
127 private void OnGetIntOperationCompleted(object arg) {
128 if ((this.GetIntCompleted != null)) {
129 System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
130 this.GetIntCompleted(this, new GetIntCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
131 }
132 }
133
134 /**//// <remarks/>
135 public new void CancelAsync(object userState) {
136 base.CancelAsync(userState);
137 }
138
139 private bool IsLocalFileSystemWebService(string url) {
140 if (((url == null)
141 || (url == string.Empty))) {
142 return false;
143 }
144 System.Uri wsUri = new System.Uri(url);
145 if (((wsUri.Port >= 1024)
146 && (string.Compare(wsUri.Host, "localHost", System.StringComparison.OrdinalIgnoreCase) == 0))) {
147 return true;
148 }
149 return false;
150 }
151 }
152
153 /**//// <remarks/>
154 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.42")]
155 public delegate void HelloWorldCompletedEventHandler(object sender, HelloWorldCompletedEventArgs e);
156
157 /**//// <remarks/>
158 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.42")]
159 [System.Diagnostics.DebuggerStepThroughAttribute()]
160 [System.ComponentModel.DesignerCategoryAttribute("code")]
161 public partial class HelloWorldCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
162
163 private object[] results;
164
165 internal HelloWorldCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
166 base(exception, cancelled, userState) {
167 this.results = results;
168 }
169
170 /**//// <remarks/>
171 public string Result {
172 get {
173 this.RaiseExceptionIfNecessary();
174 return ((string)(this.results[0]));
175 }
176 }
177 }
178
179 /**//// <remarks/>
180 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.42")]
181 public delegate void GetIntCompletedEventHandler(object sender, GetIntCompletedEventArgs e);
182
183 /**//// <remarks/>
184 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "2.0.50727.42")]
185 [System.Diagnostics.DebuggerStepThroughAttribute()]
186 [System.ComponentModel.DesignerCategoryAttribute("code")]
187 public partial class GetIntCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
188
189 private object[] results;
190
191 internal GetIntCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
192 base(exception, cancelled, userState) {
193 this.results = results;
194 }
195
196 /**//// <remarks/>
197 public int Result {
198 get {
199 this.RaiseExceptionIfNecessary();
200 return ((int)(this.results[0]));
201 }
202 }
203 }
204}
205
206#pragma warning restore 1591
我们知道Web服务主要是通过Http的Soap协议发送和接收的。我们看此代理类的基类是SoapHttpClientProtocol,也就是说此代理类封装了很多协议的发送和接收,我们使用起来非常方便,不用管底层的协议的处理,这也正是代理模式的优点:对类的控制容易性。
另外一方面,此代理类怎么和基于事件的异步这么相似呢?
(1)基于事件的异步模式可以采用多种形式,具体取决于某个特定类支持的操作的复杂程度。最简单的类可能只有一个 MethodNameAsync 方法和一个对应的 MethodNameCompleted 事件。更复杂的类可能有若干个 MethodNameAsync 方法(每种方法都有一个对应的 MethodNameCompleted 事件),以及这些方法的同步版本。这些类分别支持各种异步方法的取消、进度报告和增量结果。
异步方法可能还支持多个挂起的调用(多个并行调用),A:允许您的代码在此方法完成其他挂起的操作之前调用此方法任意多次。若要正确处理此种情况,必须让您的应用程序能够跟踪各个操作的完成。
而此代理类每个方法,比如HelloWorld同步方法,也有相对应的HelloWorldAsync()和HelloWorldAsync(object userState)异步方法。但要注意的是这2个异步方法的返回值是void,这是因为这些方法是基于事件的,标注的红色A也正说明了这点。
下边简述下基于事件的异步模式:
1。概述
基于事件的异步模式具有多线程应用程序的优点,同时隐匿了多线程设计中固有的许多复杂问题。使用支持此模式的类,您将能够:
“在后台”执行耗时任务(例如下载和数据库操作),但不会中断您的应用程序。
同时执行多个操作,每个操作完成时都会接到通知。
等待资源变得可用,但不会停止(“挂起”)您的应用程序。
使用熟悉的事件和委托模型与挂起的异步操作通信。有关使用事件处理程序和委托的更多信息,请参见事件和委托。
支持基于事件的异步模式的类将有一个或多个名为 MethodNameAsync 的方法。这些方法可能会创建同步版本的镜像,这些同步版本会在当前线程上执行相同的操作。此类还可能有一个 MethodNameCompleted 事件,而且它可能会有一个 MethodNameAsyncCancel(或只是 CancelAsync)方法。
2。基于事件的异步模式的特征
基于事件的异步模式可以采用多种形式,具体取决于某个特定类支持的操作的复杂程度。最简单的类可能只有一个 MethodNameAsync 方法和一个对应的 MethodNameCompleted 事件。更复杂的类可能有若干个 MethodNameAsync 方法(每种方法都有一个对应的 MethodNameCompleted 事件),以及这些方法的同步版本。这些类分别支持各种异步方法的取消、进度报告和增量结果。
异步方法可能还支持多个挂起的调用(多个并行调用),允许您的代码在此方法完成其他挂起的操作之前调用此方法任意多次。若要正确处理此种情况,必须让您的应用程序能够跟踪各个操作的完成。
3。异步方法重载
异步操作可以有两个重载:单调用和多调用。您可以通过方法签名来区分这两种形式:多调用形式有一个额外的参数,即 userState。使用这种形式,您的代码可以多次调用 Method1Async(string param, object userState),而不必等待任何挂起的异步操作的完成。另一方面,如果您尝试在前一个调用尚未完成时调用 Method1Async(string param),该方法将引发 InvalidOperationException。
多调用重载的 userState 参数可帮助您区分各个异步操作。您应分别为各个 Method1Async(string param, object userState) 调用提供一个唯一值(例如 GUID 或哈希代码);这样,当各个操作完成时,您的事件处理程序便可以确定哪个操作的实例引发了完成事件。
4。跟踪挂起的操作
如果您使用多调用重载,您的代码将需要跟踪挂起的任务的 userState 对象(任务 ID)。对于每个 Method1Async(string param, object userState) 调用,您通常应生成一个新的、唯一的 userState 对象并将此对象添加到集合中。当对应于此 userState 对象的任务引发完成事件时,您的完成方法实现将检查 System.ComponentModel.AsyncCompletedEventArgs.UserState 并将此对象从集合中删除。在以这种方式使用时,userState 参数充当任务 ID 的角色。
注意 |
---|
在为您对多调用重载的调用中的 userState 提供唯一值时,一定要小心。如果任务 ID 不唯一,将导致异步类引发 ArgumentException。 |
5。取消挂起的操作
我们必须能够在异步操作完成之前随时取消它们,这一点很重要。实现基于事件的异步模式的类将有一个 CancelAsync 方法(如果有多个异步方法)或 MethodNameAsyncCancel 方法(如果只有一个异步方法)。
允许多个调用的方法采用 userState 参数,此参数可用来跟踪各个任务的生存期。CancelAsync 采用 userState 参数,此参数允许您取消特定的挂起任务。
一次只支持一个挂起的操作的方法(如 Method1Async(string param))是不可取消的。
6。接收进度更新和增量结果
符合基于事件的异步模式的类可以为跟踪进度和增量结果提供事件。此事件通常叫做 ProgressChanged 或 MethodNameProgressChanged,它对应的事件处理程序会带有一个 ProgressChangedEventArgs 参数。
ProgressChanged 事件的事件处理程序可以检查 System.ComponentModel.ProgressChangedEventArgs.ProgressPercentage 属性来确定异步任务完成的百分比。此属性的范围是 0 到 100,可用来更新 ProgressBar 的 Value 属性。如果有多个异步操作挂起,您可以使用 System.ComponentModel.ProgressChangedEventArgs.UserState 属性来分辨出哪个操作在报告进度。
一些类可能会在异步操作继续时报告增量结果。这些结果将保存的派生自 ProgressChangedEventArgs 的类中,并显示为此派生类中的属性。您可以在 ProgressChanged 事件的事件处理程序中访问这些结果,就像访问 ProgressPercentage 属性一样。如果有多个异步操作挂起,您可以使用 UserState 属性来分辨出哪个操作在报告增量结果。
- 基于事件的异步编程和Web服务
- 基于事件的异步编程
- 异步编程:基于事件的异步编程模式(EMP)
- 基于事件的异步编程模式
- Web服务的异步和同步调用
- 基于事件的C#异步编程模式浅析
- 基于事件的 JavaScript 编程:异步与同步
- 基于事件的JavaScript编程:异步与同步
- 基于事件的 JavaScript 编程:异步与同步
- [你必须知道的异步编程]——基于事件的异步编程模式
- [你必须知道的异步编程]——基于事件的异步编程模式 (EAP)
- 基于Web和二维码的文件传输服务
- 基于事件的异步模式
- Socket异步编程之基于事件
- 异步编程和事件模型
- 理解Node.js的事件驱动和异步编程
- 基于任务的异步编程
- 基于Socket的多线程和异步非阻塞模式编程
- ssh整合——运行tomcat报错:严重: action: null...Error creating bean with name 'sessionFactory' .....org.apache.commons.collections.Sequence
- 深夜 又想起那一幕幕
- 在RedHat Linux上安装SM
- web service实现原理与异步调用
- 自己动手清理Windows右键菜单
- 基于事件的异步编程和Web服务
- 删除你的一切记忆
- oracle内存分配与调整
- 小波聚类与OPTICS聚类的适用性
- XPath手册 [源于ZVON]
- 家常菜的烹饪方法和技巧(转)
- pchome以首页链接来换取软件发布的方式不可取: 幼稚,小家子气,无法受人尊重
- 在Java中读写Excel文件
- strace命令用法