|
源代码网推荐
异步Web服务(2)
源代码网推荐
和XML Web服务异步地通讯 源代码网推荐 源代码网推荐 和一个XML Web服务异步通讯遵循被Microsoft.NET Framework其它部分使用的异步设计模式。然而,在你取得那些细节之前,重要的是注意一个XML Web服务不必特意的写来处理用于异步调用的异步请求。你使用Wsdl.exe为你的客户端创建的代理类自动地创建用于异步调用XML Web服务方法的方法。即使只有一个XML Web服务方法的同步实现也是这样的。 源代码网推荐 源代码网推荐 .NET Framework异步方法调用设计模式 源代码网推荐 源代码网推荐 用于调用异步方法的设计模式,尤其是用于.NET Framework,针对每个同步方法分别有两个异步方法。对每个同步方法,都有一个Begin异步方法和一个End异步方法。Begin方法被客户端调用来开始方法调用。也就是说,客户端指示这个方法来开始处理方法调用,但是立即返回。End方法被客户端调用来取得XML Web服务方法调用执行的处理结果。 源代码网推荐 源代码网推荐 一个客户端如何知道何时调用End方法?.NET Framework定义了两种方法来实现客户端判断其时间。第一种是传送一个回调函数到Begin方法,当方法已经完成处理的时候调用。第二个方法是使用WaitHandle类的一个方法来导致客户端等待方法完成。当一个客户端实现第二个方法,并且调用Begin方法,返回值不是XML Web服务方法指定的数据类型,而是一个实现IAsyncResult接口的类型。IAsyncResult接口包含一个WaitHandle类型的AsyncWaitHandle属性,实现支持等待同步对象变为带有WaitHandle.WaitOne、WaitAny和WaitAll标记的方法。当一个同步对象被标记的时候,它指示等待特定的资源的线程可以访问资源的。如果一个XML Web服务客户端使用wait方法仅仅异步地调用一个XML Web服务方法,那么它可以调用WaitOne来等待XML Web服务方法完成处理。 源代码网推荐 源代码网推荐 重要的是注意不管客户端选择来与XML Web服务异步通讯的两种方法中的哪一种,SOAP消息发送和接收都与同步通信时吻合。也就是说,只有一个SOAP请求和SOAP响应通过网络发送和接收。代理类通过使用一个不同的线程而不是客户端用来调用Begin方法的线程来处理SOAP响应。因此,客户端可以继续执行线程上的其它的工作,而代理类处理接收和操作SOAP响应。 源代码网推荐 源代码网推荐 实现一个产生异步的方法调用的XML Web服务客户端 源代码网推荐 源代码网推荐 用于从使用ASP.NET创建的XML Web服务客户端产生一个到XML Web服务的异步调用的体系结构被嵌入.NET Framework和由Wsdl.exe构造的代理类中。用于异步调用的设计模式被.NET Framework定义,代理类提供和一个XML Web服务异步通信的机制。当一个用于XML Web服务的代理类被使用Wsdl.exe构造的时候,有三个方法分别被创建,用于XML Web服务中的公共XML Web服务方法。下面的表格描述那三个方法。 源代码网推荐 源代码网推荐 代理类中的方法名 描述 源代码网推荐 源代码网推荐 <NameOfWebServiceMethod> 同步发送用于名为<NameOfWebServiceMethod>的XML Web服务方法的消息。 源代码网推荐 源代码网推荐 Begin<NameOfWebServiceMethod> 开始与名为<NameOfWebServiceMethod>的XML Web服务方法的异步消息通信。 源代码网推荐 源代码网推荐 End<NameOfWebServiceMethod> 结束与名为<NameOfWebServiceMethod>的XML Web服务方法的异步消息通信,从XML Web服务方法中取得完成的消息。 源代码网推荐 源代码网推荐 下面的代码示例是一个XML Web服务方法,它可能花费相对长的时间来完成处理。因此,当你应该设置你的XML Web服务客户端来异步地调用XML Web服务方法的时候,它是一个很好的示例。 源代码网推荐 源代码网推荐
|
[C#] 源代码网推荐<%@ WebService Language="C#" Class="PrimeFactorizer" %> 源代码网推荐 源代码网推荐using System; 源代码网推荐using System.Collections; 源代码网推荐using System.Web.Services; 源代码网推荐 源代码网推荐class PrimeFactorizer { 源代码网推荐 源代码网推荐 [WebMethod] 源代码网推荐 public long[] Factorize(long factorizableNum){ 源代码网推荐 ArrayList outList = new ArrayList(); 源代码网推荐 long i = 0; 源代码网推荐 int j; 源代码网推荐 try{ 源代码网推荐 long Check = factorizableNum; 源代码网推荐 源代码网推荐 //Go through every possible integer 源代码网推荐 //factor between 2 and factorizableNum / 2. 源代码网推荐 //Thus, for 21, check between 2 and 10. 源代码网推荐 for (i = 2; i < (factorizableNum / 2); i++){ 源代码网推荐 while(Check % i == 0){ 源代码网推荐 outList.Add(i); 源代码网推荐 Check = (Check/i); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 //Double-check to see how many prime factors have been added. 源代码网推荐 //If none, add 1 and the number. 源代码网推荐 j = outList.Count; 源代码网推荐 if (j == 0) { 源代码网推荐 outList.Add(1); 源代码网推荐 outList.Add(factorizableNum); 源代码网推荐 } 源代码网推荐 j = outList.Count; 源代码网推荐 源代码网推荐 //Return the results and 源代码网推荐 //create an array to hold them. 源代码网推荐 long[] primeFactor = new long[j]; 源代码网推荐 for (j = 0; j < outList.Count; j++){ 源代码网推荐 //Pass the values one by one, making sure 源代码网推荐 //to convert them to type ulong. 源代码网推荐 primeFactor[j] = Convert.ToInt64(outList[j]); 源代码网推荐 } 源代码网推荐 return primeFactor; 源代码网推荐 } 源代码网推荐 catch (Exception) { 源代码网推荐 return null; 源代码网推荐 } 源代码网推荐 } 源代码网推荐} 源代码网推荐 源代码网推荐[Visual Basic] 源代码网推荐<%@ WebService Class="PrimeFactorizer" Language="VB" %> 源代码网推荐Imports System 源代码网推荐Imports System.Collections 源代码网推荐Imports System.Web.Services 源代码网推荐 源代码网推荐Public Class PrimeFactorizer 源代码网推荐<WebMethod> _ 源代码网推荐Public Function Factorize(factorizableNum As Long) As Long() 源代码网推荐 Dim outList As New ArrayList() 源代码网推荐 Dim i As Long = 0 源代码网推荐 Dim j As Integer 源代码网推荐 Try 源代码网推荐 Dim Check As Long = factorizableNum 源代码网推荐 源代码网推荐 "Go through every possible integer 源代码网推荐 "factor between 2 and factorizableNum / 2. 源代码网推荐 "Thus, for 21, check between 2 and 10. 源代码网推荐 For i = 2 To CLng(factorizableNum / 2) - 1 源代码网推荐 While Check Mod i = 0 源代码网推荐 outList.Add(i) 源代码网推荐 Check = CLng(Check / i) 源代码网推荐 End While 源代码网推荐 Next i 源代码网推荐 "Double-check to see how many prime factors have been added. 源代码网推荐 "If none, add 1 and the number. 源代码网推荐 j = outList.Count 源代码网推荐 If j = 0 Then 源代码网推荐 outList.Add(1) 源代码网推荐 outList.Add(factorizableNum) 源代码网推荐 End If 源代码网推荐 j = outList.Count 源代码网推荐 源代码网推荐 "Return the results and 源代码网推荐 "create an array to hold them. 源代码网推荐 Dim primeFactor(j - 1) As Long 源代码网推荐 For j = 0 To outList.Count - 1 源代码网推荐 "Pass the values one by one, making sure 源代码网推荐 "to convert them to type ulong. 源代码网推荐 primeFactor(j) = CLng(outList(j)) 源代码网推荐 Next j 源代码网推荐 Return primeFactor 源代码网推荐 Catch 源代码网推荐 Return Nothing 源代码网推荐 End Try 源代码网推荐End Function 源代码网推荐End Class |
源代码网推荐 下面的代码示例是一个Wsdl.exe生成的代理类的一部分,用于上述XML Web服务方法。注意BeginFactorize和EndFactorize方法,因为它们被用来与Factorize XML Web服务方法异步通信。 源代码网推荐 源代码网推荐
|
public class PrimeFactorizer : System.Web.Services.Protocols.SoapHttpClientProtocol { 源代码网推荐 源代码网推荐 public long[] Factorize(long factorizableNum) { 源代码网推荐 object[] results = this.Invoke("Factorize", new object[] { factorizableNum}); 源代码网推荐 return ((long[])(results[0])); 源代码网推荐 } 源代码网推荐 源代码网推荐 public System.IAsyncResult BeginFactorize(long factorizableNum, System.AsyncCallback callback, object asyncState) { 源代码网推荐 return this.BeginInvoke("Factorize", new object[] { 源代码网推荐 factorizableNum}, callback, asyncState); 源代码网推荐 } 源代码网推荐 源代码网推荐 public long[] EndFactorize(System.IAsyncResult asyncResult) { 源代码网推荐 object[] results = this.EndInvoke(asyncResult); 源代码网推荐 return ((long[])(results[0])); 源代码网推荐 } 源代码网推荐} |
源代码网推荐 有两个方法用来和XML Web服务方法异步通信。下面的代码示例说明了如何与一个XML Web服务方法异步通信,并且使用回调函数来取得XML Web服务方法的结果。 源代码网推荐 源代码网推荐
|
[C#] 源代码网推荐using System; 源代码网推荐using System.Runtime.Remoting.Messaging; 源代码网推荐using MyFactorize; 源代码网推荐 源代码网推荐class TestCallback 源代码网推荐{ 源代码网推荐 public static void Main(){ 源代码网推荐 long factorizableNum = 12345; 源代码网推荐 PrimeFactorizer pf = new PrimeFactorizer(); 源代码网推荐 源代码网推荐 //Instantiate an AsyncCallback delegate to use as a parameter 源代码网推荐 //in the BeginFactorize method. 源代码网推荐 AsyncCallback cb = new AsyncCallback(TestCallback.FactorizeCallback); 源代码网推荐 源代码网推荐 // Begin the Async call to Factorize, passing in our 源代码网推荐 // AsyncCalback delegate and a reference 源代码网推荐 // to our instance of PrimeFactorizer. 源代码网推荐 IAsyncResult ar = pf.BeginFactorize(factorizableNum, cb, pf); 源代码网推荐 源代码网推荐 // Keep track of the time it takes to complete the async call 源代码网推荐 // as the call proceeds. 源代码网推荐 int start = DateTime.Now.Second; 源代码网推荐 int currentSecond = start; 源代码网推荐 while (ar.IsCompleted == false){ 源代码网推荐 if (currentSecond < DateTime.Now.Second) { 源代码网推荐 currentSecond = DateTime.Now.Second; 源代码网推荐 Console.WriteLine("Seconds Elapsed..." + (currentSecond - start).ToString() ); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 // Once the call has completed, you need a method to ensure the 源代码网推荐 // thread executing this Main function 源代码网推荐 // doesn"t complete prior to the call-back function completing. 源代码网推荐 Console.Write("Press Enter to quit"); 源代码网推荐 int quitchar = Console.Read(); 源代码网推荐 } 源代码网推荐 // Set up a call-back function that is invoked by the proxy class 源代码网推荐 // when the asynchronous operation completes. 源代码网推荐 public static void FactorizeCallback(IAsyncResult ar) 源代码网推荐 { 源代码网推荐 // You passed in our instance of PrimeFactorizer in the third 源代码网推荐 // parameter to BeginFactorize, which is accessible in the 源代码网推荐 // AsyncState property. 源代码网推荐 PrimeFactorizer pf = (PrimeFactorizer) ar.AsyncState; 源代码网推荐 long[] results; 源代码网推荐 源代码网推荐 // Get the completed results. 源代码网推荐 results = pf.EndFactorize(ar); 源代码网推荐 源代码网推荐 //Output the results. 源代码网推荐 Console.Write("12345 factors into: "); 源代码网推荐 int j; 源代码网推荐 for (j = 0; j<results.Length;j++){ 源代码网推荐 if (j == results.Length - 1) 源代码网推荐 Console.WriteLine(results[j]); 源代码网推荐 else 源代码网推荐 Console.Write(results[j] + ", "); 源代码网推荐 } 源代码网推荐 } 源代码网推荐} 源代码网推荐 源代码网推荐[Visual Basic] 源代码网推荐Imports System 源代码网推荐Imports System.Runtime.Remoting.Messaging 源代码网推荐Imports MyFactorize 源代码网推荐 源代码网推荐Public Class TestCallback 源代码网推荐Public Shared Sub Main() 源代码网推荐Dim factorizableNum As Long = 12345 源代码网推荐Dim pf As PrimeFactorizer = new PrimeFactorizer() 源代码网推荐 源代码网推荐"Instantiate an AsyncCallback delegate to use as a parameter 源代码网推荐" in the BeginFactorize method. 源代码网推荐Dim cb as AsyncCallback 源代码网推荐cb = new AsyncCallback(AddressOf TestCallback.FactorizeCallback) 源代码网推荐 源代码网推荐" Begin the Async call to Factorize, passing in the 源代码网推荐" AsyncCallback delegate and a reference to our instance 源代码网推荐" of PrimeFactorizer. 源代码网推荐Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, cb, pf) 源代码网推荐 源代码网推荐" Keep track of the time it takes to complete the async call as 源代码网推荐" the call proceeds. 源代码网推荐Dim start As Integer = DateTime.Now.Second 源代码网推荐Dim currentSecond As Integer = start 源代码网推荐Do while (ar.IsCompleted = false) 源代码网推荐If (currentSecond < DateTime.Now.Second) Then 源代码网推荐 currentSecond = DateTime.Now.Second 源代码网推荐 Console.WriteLine("Seconds Elapsed..." + (currentSecond - start).ToString() ) 源代码网推荐End If 源代码网推荐Loop 源代码网推荐 源代码网推荐" Once the call has completed, you need a method to ensure the 源代码网推荐" thread executing this Main function 源代码网推荐" doesn"t complete prior to the callback function completing. 源代码网推荐Console.Write("Press Enter to quit") 源代码网推荐Dim quitchar As Integer = Console.Read() 源代码网推荐End Sub 源代码网推荐 源代码网推荐" Set up the call-back function that is invoked by the proxy 源代码网推荐" class when the asynchronous operation completes. 源代码网推荐Public Shared Sub FactorizeCallback(ar As IAsyncResult) 源代码网推荐 源代码网推荐" You passed in the instance of PrimeFactorizer in the third 源代码网推荐" parameter to BeginFactorize, which is accessible in the 源代码网推荐" AsyncState property. 源代码网推荐 源代码网推荐Dim pf As PrimeFactorizer = ar.AsyncState 源代码网推荐Dim results() as Long 源代码网推荐 源代码网推荐" Get the completed results. 源代码网推荐results = pf.EndFactorize(ar) 源代码网推荐 源代码网推荐"Output the results. 源代码网推荐Console.Write("12345 factors into: ") 源代码网推荐Dim j as Integer 源代码网推荐For j = 0 To results.Length - 1 源代码网推荐 If j = (results.Length - 1) Then 源代码网推荐 Console.WriteLine(results(j) ) 源代码网推荐 Else 源代码网推荐 Console.Write(results(j).ToString + ", ") 源代码网推荐 End If 源代码网推荐Next j 源代码网推荐End Sub 源代码网推荐End Class |
源代码网推荐 下面的代码示例说明了如何与一个XML Web服务方法异步通信,然后使用一个同步对象来等待处理结束。 源代码网推荐 源代码网推荐
|
[C#] 源代码网推荐// -----------------------------------------------------------------------// Async Variation 2. 源代码网推荐// Asynchronously invoke the Factorize method, 源代码网推荐//without specifying a call back. 源代码网推荐using System; 源代码网推荐using System.Runtime.Remoting.Messaging; 源代码网推荐// MyFactorize, is the name of the namespace in which the proxy class is 源代码网推荐// a member of for this sample. 源代码网推荐using MyFactorize; 源代码网推荐 源代码网推荐class TestCallback 源代码网推荐{ 源代码网推荐 public static void Main(){ 源代码网推荐 long factorizableNum = 12345; 源代码网推荐 PrimeFactorizer pf = new PrimeFactorizer(); 源代码网推荐 源代码网推荐 // Begin the Async call to Factorize. 源代码网推荐 IAsyncResult ar = pf.BeginFactorize(factorizableNum, null, null); 源代码网推荐 源代码网推荐 // Wait for the asynchronous operation to complete. 源代码网推荐 ar.AsyncWaitHandle.WaitOne(); 源代码网推荐 源代码网推荐 // Get the completed results. 源代码网推荐 long[] results; 源代码网推荐 results = pf.EndFactorize(ar); 源代码网推荐 源代码网推荐 //Output the results. 源代码网推荐 Console.Write("12345 factors into: "); 源代码网推荐 int j; 源代码网推荐 for (j = 0; j<results.Length;j++){ 源代码网推荐 if (j == results.Length - 1) 源代码网推荐 Console.WriteLine(results[j]); 源代码网推荐 else 源代码网推荐 Console.Write(results[j] + ", "); 源代码网推荐 } 源代码网推荐 } 源代码网推荐} 源代码网推荐 源代码网推荐[Visual Basic] 源代码网推荐Imports System 源代码网推荐Imports System.Runtime.Remoting.Messaging 源代码网推荐Imports MyFactorize " Proxy class namespace 源代码网推荐 源代码网推荐Public Class TestCallback 源代码网推荐Public Shared Sub Main() 源代码网推荐Dim factorizableNum As Long = 12345 源代码网推荐Dim pf As PrimeFactorizer = new PrimeFactorizer() 源代码网推荐 源代码网推荐" Begin the Async call to Factorize. 源代码网推荐Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, Nothing, Nothing) 源代码网推荐 源代码网推荐" Wait for the asynchronous operation to complete. 源代码网推荐ar.AsyncWaitHandle.WaitOne() 源代码网推荐 源代码网推荐" Get the completed results. 源代码网推荐Dim results() as Long 源代码网推荐results = pf.EndFactorize(ar) 源代码网推荐 源代码网推荐"Output the results. 源代码网推荐Console.Write("12345 factors into: ") 源代码网推荐Dim j as Integer 源代码网推荐For j = 0 To results.Length - 1 源代码网推荐 If j = (results.Length - 1) Then 源代码网推荐 Console.WriteLine(results(j) ) 源代码网推荐 Else 源代码网推荐 Console.Write(results(j).ToString + ", ") 源代码网推荐 End If 源代码网推荐Next j 源代码网推荐End Sub 源代码网推荐End Class |
源代码网推荐 注意:如果FactorizeCallback是一个需要同步化/线成亲和上下文的上下文绑定类,那么回调被通过上下文分配体系结构来分配。换句话说,相对于它的对这样的上下文的调用者,回调可能异步的执行。在方法标记上有单向修饰词的精确的语义。这指的是任何这样的方法调用可能同步地或异步地执行,相对于调用者,并且在执行控制返回给它的时候,调用者不能产生任何关于完成这样一个调用的假设。 源代码网推荐而且,在异步操作完成之前调用EndInvoke将阻塞调用者。使用相同的AsyncResult再次调用它的行为是不确定的。 源代码网推荐 源代码网推荐 Cancel方法是一个在过去一段特定时间之后取消方法处理的请求。注意它是一个客户端的请求,并且最好服务器对此有所承诺。在接收到方法已经被取消的消息之后,客户端就不必做服务器是否已经停止处理的假设了。客户端最好不要破坏资源,例如文件对象,因为服务器可能仍然需要使用它们。IAsyncResult实例的IsCompleted属性在服务器结束它的处理之后将被设置为true,不再使用任何客户端提供的资源。因此,IsCompleted属性设置为true之后,客户端就可以安全的销毁资源了。
源代码网供稿. |