明輝手游網(wǎng)中心:是一個免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

ASP.NET創(chuàng)建XML Web服務(wù)全接觸(9)

[摘要]為了改善調(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