为了改善调用阻碍线程的长期运行的方法的XML Web服务方法的性能,你应该考虑把它们作为异步的XML
Web服务方法发布。实现一个异步XML
Web服务方法允许线程在返回线程池的时候执行其他的代码。这允许增加一个线程池中的有限数目的线程,这样提高了整体性能和系统的可伸缩性。
通常,调用执行输入/输出操作的方法的XML
Web服务方法适于作为异步实现。这样的方法的例子包括和其他的XML
Web服务通讯、访问远程数据库、执行网络输入/输出和读写大文件方法。这些方法都花费大量时间执行硬件级操作,而把线程留着用来执行XML
Web服务方法程序块。如果XML Web服务方法异步实现,那么线程可以被释放来执行其他的代码。
不管一个XML
Web服务方法是否异步实现,客户端都可以与之异步通讯。使用Web服务描述语言工具(WSDL.EXE)生成的.NET客户端中的代理类来实现异步通信,即使XML
Web服务方法是同步实现。代理类包含用于与每个XML Web服务方法异步通信的Begin和End方法。因此,决定一个XML
Web服务方法到底是异步还是同步要取决于性能。
注意:实现一个异步的XML Web服务方法对客户端和服务器上的XML
Web服务之间的HTTP连接没有影响。HTTP连接既不不会关闭也不用连接池化。
实现一个异步的XML
Web服务方法
实现一个异步的XML Web服务方法遵循NET
Framework异步设计模式
把一个同步的XML
Web服务方法分解为两个方法;其中每个都带有相同的基名--一个带有以Begin开头的名称,另一个带有以End开头的名称。
Begin方法的参数表包含方法的功能中的所有的in和by引用参数。
By引用参数是作为输入参数列出的。
倒数第二个参数必须是AsyncCallback。AsyncCallback参数允许客户端提供一个委托,在方法调用完成的时候调用。当一个异步XML
Web服务方法调用另一个异步方法,这个参数可以被传入那个方法的倒数第二个参数。最后一个参数是一个对象。对象参数允许一个调用者提供状态信息给方法。当一个异步XML
Web服务方法调用另一个异步方法,这个参数可以被传入那个方法的最后一个参数。
返回值必须是IAsyncResult类型的。
下面的代码示例是一个Begin方法,有一个方法函数特定的String参数。
[C#] [WebMethod] public IAsyncResult
BeginGetAuthorRoyalties(String Author, AsyncCallback callback, object
asyncState) [Visual Basic] <WebMethod()> _ Public Function
BeginGetAuthorRoyalties(ByVal Author As String, _ ByVal callback As
AsyncCallback, ByVal asyncState As Object) _ As
IAsyncResult End方法的参数表由一个IAsyncResult类型的out和by引用参数组成。
返回值与一个同步的XML
Web服务方法的返回值类型相同。
By引用参数是作为输出参数列出的。
下面的代码示例是一个End方法,返回一个AuthorRoyalties用户定义的模式。
[C#] [WebMethod] public AuthorRoyalties
EndGetAuthorRoyalties(IAsyncResult asyncResult)
[Visual
Basic] <WebMethod()> _ Public Function EndGetAuthorRoyalties(ByVal
asyncResult As _ IAsyncResult) As
AuthorRoyalties 下面的代码示例是一个和另一个XML
Web服务方法异步通讯的异步XML Web服务方法。
[C#] using System; using System.Web.Services;
[WebService(Namespace="http://www.contoso.com/")] public class
MyService : WebService { public RemoteService
remoteService; public MyService() { // Create a new instance
of proxy class for // the XML Web service to be
called. remoteService = new RemoteService(); } // Define the
Begin method. [WebMethod] public IAsyncResult
BeginGetAuthorRoyalties(String Author,AsyncCallback callback, object
asyncState) { // Begin asynchronous communictation with a different
XML Web // service. return
remoteService.BeginReturnedStronglyTypedDS(Author, callback,asyncState); } //
Define the End method. [WebMethod] public AuthorRoyalties
EndGetAuthorRoyalties(IAsyncResultasyncResult) { // Return the
asynchronous result from the other XML Web service. return
remoteService.EndReturnedStronglyTypedDS(asyncResult); } }
[Visual
Basic] Imports
System.Web.Services <WebService(Namespace:="http://www.contoso.com/")>
_ Public Class MyService Inherits WebService Public remoteService
As RemoteService
Public Sub New() MyBase.New() ' Create a
new instance of proxy class for ' the XML Web service to be
called. remoteService = New RemoteService() End Sub
' Define
the Begin method. <WebMethod()> _ Public Function
BeginGetAuthorRoyalties(ByVal Author As String, _ ByVal callback As
AsyncCallback, ByVal asyncState As Object) _ As IAsyncResult '
Begin asynchronous communictation with a different XML Web '
service. Return remoteService.BeginReturnedStronglyTypedDS(Author,
_ callback, asyncState) End Function ' Define the End
method. <WebMethod()> _ Public Function EndGetAuthorRoyalties(ByVal
asyncResult As _ IAsyncResult) As AuthorRoyalties ' Return the
asynchronous result from the other XML Web service. Return
remoteService.EndReturnedStronglyTypedDS(asyncResult) End
Function End Class 下面的代码示例显示当一个XML
Web服务方法产生了一个以上的异步调用并且这些调用必须连续执行时如何连接这些异步调用。BeginGetAuthorRoyalties方法产生一个异步调用用来判断传入的作者名是否有效,并设置一个名为AuthorRoyaltiesCallback的中间回调来接收结果。如果作者名有效,那么那个中间回调异步调用来获得作者的版税。
[C#] using System.Web.Services; using System.Data; using
System; // This imports the proxy class for the XML Web services //
that the sample communicates with. using
AsyncWS.localhost;
namespace
AsyncWS { [WebService(Namespace="http://www.contoso.com/")] public
class MyService : System.Web.Services.WebService { public
RemoteService remoteService; public
MyService() { remo teService = new
RemoteService(); }
[WebMethod] public IAsyncResult
BeginGetAuthorRoyalties(String Author, AsyncCallback callback, Object
asyncState) { // Saves the current state for the call that gets
the author's // royalties. AsyncStateChain state = new
AsyncStateChain(); state.originalState =
asyncState; state.Author = Author; state.originalCallback =
callback;
// Creates an intermediary callback. AsyncCallback
chainedCallback =
new AsyncCallback(AuthorRoyaltiesCallback); return
remoteService.BeginGetAuthors(chainedCallback,state); } //
Intermediate method to handle chaining the // asynchronous
calls. public void AuthorRoyaltiesCallback(IAsyncResult
ar) { AsyncStateChain state =
(AsyncStateChain)ar.AsyncState; RemoteService rs = new
RemoteService();
// Gets the result from the call to
GetAuthors. Authors allAuthors =
rs.EndGetAuthors(ar);
Boolean found = false; // Verifies
that the requested author is valid. int i = 0; DataRow
row; while (i < allAuthors.authors.Rows.Count &&
!found) { row = allAuthors.authors.Rows[i]; if
(row["au_lname"].ToString() == state.Author) { found =
true; } i++; } if
(found) { AsyncCallback cb = state.originalCallback; //
Calls the second XML Web service, because the author is //
valid. rs.BeginReturnedStronglyTypedDS(state.Author,cb,state); } else { //
Cannot throw the exception in this function or the XML Web //
service will hang. So, set the state argument to the // exception
and let the End method of the chained XML Web // service check for
it. ArgumentException ex = new ArgumentException( "Author
does not exist.","Author"); AsyncCallback cb =
state.originalCallback; // Call the second XML Web service, setting
the state to an //
exception. rs.BeginReturnedStronglyTypedDS(state.Author,cb,ex); } }
[WebMethod] public
AuthorRoyalties EndGetAuthorRoyalties(IAsyncResult asyncResult)
{ // Check whehter the first XML Web service threw an
exception. if (asyncResult.AsyncState is
ArgumentException) throw (ArgumentException)
asyncResult.AsyncState; else return
remoteService.EndReturnedStronglyTypedDS(asyncResult); } } //
Class to wrap the callback and state for the intermediate //
asynchronous operation. public class AsyncStateChain { public
AsyncCallback originalCallback; public Object
originalState; public String Author; } }
[Visual
Basic]
Imports System.Web.Services Imports
System.Data Imports System ' This imports the proxy class for the
XML Web services ' that the sample communicates with. Imports
AsyncWS_VB.localhost
Namespace
AsyncWs
<WebService(Namespace:="http://www.contoso.com/")>
_ Public Class MyService Inherits WebService Public remoteService
As remoteService Public Sub New() MyBase.New() remoteService =
New localhost.RemoteService() End Sub ' Defines the Begin
method. <WebMethod()> _ Public Function
BeginGetAuthorRoyalties(ByVal Author As String, _ ByVal callback As
AsyncCallback, ByVal asyncState As Object) _ As IAsyncResult ' Saves
the current state for the call that gets the author's '
royalties. Dim state As AsyncStateChain = New
AsyncStateChain() state.originalState = asyncState state.Author =
Author state.originalCallback = callback
' Creates an
intermediary callback. Dim chainedCallback As AsyncCallback = New
AsyncCallback( _ AddressOf AuthorRoyaltiesCallback) ' Begin
asynchronous communictation with a different XML Web '
service. Return remoteService.BeginGetAuthors(chainedCallback,
state) End Function
' Intermediate method to handle chaining the
asynchronous calls. Public Sub AuthorRoyaltiesCallback(ByVal ar As
IAsyncResult) Dim state As AsyncStateChain = CType(ar.AsyncState,
_ AsyncStateChain) Dim rs As RemoteService = New
RemoteService()
' Gets the result from the call to
GetAuthors. Dim allAuthors As Authors = rs.EndGetAuthors(ar) Dim
found As Boolean = False
' Verifies that the requested author is
valid. Dim i As Integer = 0 Dim row As DataRow While (i <
allAuthors.authors.Rows.Count And (Not found)) row =
a[1] [2] 下一页 |