ASP.NET創(chuàng)建XML Web服務(wù)全接觸(9)
發(fā)表時間:2024-02-14 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]為了改善調(diào)用阻礙線程的長期運(yùn)行的方法的XML Web服務(wù)方法的性能,你應(yīng)該考慮把它們作為異步的XML Web服務(wù)方法發(fā)布。實(shí)現(xiàn)一個異步XML Web服務(wù)方法允許線程在返回線程池的時候執(zhí)行其他的代碼。這允許增加一個線程池中的有限數(shù)目的線程,這樣提高了整體性能和系統(tǒng)的可伸縮性! ⊥ǔ,調(diào)用執(zhí)行輸入/...
為了改善調(diào)用阻礙線程的長期運(yùn)行的方法的XML Web服務(wù)方法的性能,你應(yīng)該考慮把它們作為異步的XML Web服務(wù)方法發(fā)布。實(shí)現(xiàn)一個異步XML Web服務(wù)方法允許線程在返回線程池的時候執(zhí)行其他的代碼。這允許增加一個線程池中的有限數(shù)目的線程,這樣提高了整體性能和系統(tǒng)的可伸縮性。
通常,調(diào)用執(zhí)行輸入/輸出操作的方法的XML Web服務(wù)方法適于作為異步實(shí)現(xiàn)。這樣的方法的例子包括和其他的XML Web服務(wù)通訊、訪問遠(yuǎn)程數(shù)據(jù)庫、執(zhí)行網(wǎng)絡(luò)輸入/輸出和讀寫大文件方法。這些方法都花費(fèi)大量時間執(zhí)行硬件級操作,而把線程留著用來執(zhí)行XML Web服務(wù)方法程序塊。如果XML Web服務(wù)方法異步實(shí)現(xiàn),那么線程可以被釋放來執(zhí)行其他的代碼。
不管一個XML Web服務(wù)方法是否異步實(shí)現(xiàn),客戶端都可以與之異步通訊。使用Web服務(wù)描述語言工具(WSDL.EXE)生成的.NET客戶端中的代理類來實(shí)現(xiàn)異步通信,即使XML Web服務(wù)方法是同步實(shí)現(xiàn)。代理類包含用于與每個XML Web服務(wù)方法異步通信的Begin和End方法。因此,決定一個XML Web服務(wù)方法到底是異步還是同步要取決于性能。
注意:實(shí)現(xiàn)一個異步的XML Web服務(wù)方法對客戶端和服務(wù)器上的XML Web服務(wù)之間的HTTP連接沒有影響。HTTP連接既不不會關(guān)閉也不用連接池化。
實(shí)現(xiàn)一個異步的XML Web服務(wù)方法
實(shí)現(xiàn)一個異步的XML Web服務(wù)方法遵循NET Framework異步設(shè)計(jì)模式
把一個同步的XML Web服務(wù)方法分解為兩個方法;其中每個都帶有相同的基名--一個帶有以Begin開頭的名稱,另一個帶有以End開頭的名稱。
Begin方法的參數(shù)表包含方法的功能中的所有的in和by引用參數(shù)。
By引用參數(shù)是作為輸入?yún)?shù)列出的。
倒數(shù)第二個參數(shù)必須是AsyncCallback。AsyncCallback參數(shù)允許客戶端提供一個委托,在方法調(diào)用完成的時候調(diào)用。當(dāng)一個異步XML Web服務(wù)方法調(diào)用另一個異步方法,這個參數(shù)可以被傳入那個方法的倒數(shù)第二個參數(shù)。最后一個參數(shù)是一個對象。對象參數(shù)允許一個調(diào)用者提供狀態(tài)信息給方法。當(dāng)一個異步XML Web服務(wù)方法調(diào)用另一個異步方法,這個參數(shù)可以被傳入那個方法的最后一個參數(shù)。
返回值必須是IAsyncResult類型的。
下面的代碼示例是一個Begin方法,有一個方法函數(shù)特定的String參數(shù)。
[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方法的參數(shù)表由一個IAsyncResult類型的out和by引用參數(shù)組成。
返回值與一個同步的XML Web服務(wù)方法的返回值類型相同。
By引用參數(shù)是作為輸出參數(shù)列出的。
下面的代碼示例是一個End方法,返回一個AuthorRoyalties用戶定義的模式。
[C#] [WebMethod] public AuthorRoyalties EndGetAuthorRoyalties(IAsyncResult asyncResult)
[Visual Basic] <WebMethod()> _ Public Function EndGetAuthorRoyalties(ByVal asyncResult As _ IAsyncResult) As AuthorRoyalties |
下面的代碼示例是一個和另一個XML Web服務(wù)方法異步通訊的異步XML Web服務(wù)方法。
[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 |
下面的代碼示例顯示當(dāng)一個XML Web服務(wù)方法產(chǎn)生了一個以上的異步調(diào)用并且這些調(diào)用必須連續(xù)執(zhí)行時如何連接這些異步調(diào)用。BeginGetAuthorRoyalties方法產(chǎn)生一個異步調(diào)用用來判斷傳入的作者名是否有效,并設(shè)置一個名為AuthorRoyaltiesCallback的中間回調(diào)來接收結(jié)果。如果作者名有效,那么那個中間回調(diào)異步調(diào)用來獲得作者的版稅。
[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 = allAuthors.authors.Rows(i) If (row("au_lname").ToString() = state.Author) Then found = True End If i = i + 1 End While
If (found) Then Dim cb As AsyncCallback = 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. Dim ex As ArgumentException = New ArgumentException( "Author does not exist.", "Author") Dim cb As AsyncCallback = state.originalCallback ' Call the second XML Web service, setting the state to an ' exception. rs.BeginReturnedStronglyTypedDS(state.Author, cb, ex) End If End Sub
' Define the End method. <WebMethod()> _ Public Function EndGetAuthorRoyalties(ByVal asyncResult As _ IAsyncResult) As localhost.AuthorRoyalties ' Return the asynchronous result from the other XML Web service. Return remoteService.EndReturnedStronglyTypedDS(asyncResult) End Function
End Class
' Class to wrap the callback and state for the intermediate asynchronous ' operation. Public Class AsyncStateChain Public originalCallback As AsyncCallback Public originalState As Object Public Author As String End Class End Namespace |