日期:2014-05-16  浏览次数:20594 次

服务器端异步 Web 方法

服务器端异步 Web 方法

何时采用异步 Web 方法

在确定是否适合在您的应用程序中采用异步 Web 方法时,有几个问题需要考虑。首先,调用的 BeginXXX 函数必须返回一个 IAsyncResult 接口。IAsyncResult 是从多个异步 I/O 操作返回的,这些操作包括访问数据流、进行 Microsoft® Windows® 套接字调用、执行文件 I/O、与其他硬件设备交互、调用异步方法,当然也包括调用其他 Web 服务。您可以从这些异步操作中得到 IAsyncResult,以便从 BeginXXX 函数返回它。您也可以创建自己的类以实现 IAsyncResult 接口,但随后可能需要以某种方式包装前面提到的某个 I/O 操作。

对于前面提到的大多数异步操作,使用异步 Web 方法包装后端异步调用很有意义,可以使 Web 服务代码更有效。但使用委托进行异步方法调用时除外。委托会导致异步方法调用占用进程线程池中的某个线程。不幸的是,ASMX 处理程序为进入的请求提供服务时同样要使用这些线程。所以与对硬件或网络资源执行真正 I/O 操作的调用不同,使用委托的异步方法调用在执行时仍将占用其中一个进程线程。您也可以占用原来的线程,同步运行您的 Web 方法。

下面的示例显示了一个调用后端 Web 服务的异步 Web 方法。它已经使用 WebMethod 属性标识了 BeginGetAge 和 EndGetAge 方法,以便异步运行。此异步 Web 方法的代码调用名为 UserInfoQuery 的后端 Web 方法,以获得它需要返回的信息。对 UserInfoQuery 的调用被异步执行,并被传递到 AsyncCallback 函数,后者被传递到 BeginGetAge 方法。这将导致当后端请求完成时,调用内部回调函数。然后,回调函数将调用 EndGetAge 方法以完成请求。此示例中的代码比前面示例中的代码简单得多,并且还具有另外一个优点,即没有在与为中间层 Web 方法请求提供服务的相同线程池中启动后端处理。

[WebService]

public class GetMyInfo : System.Web.Services.WebService

{

[WebMethod]

public IAsyncResult BeginGetAge(AsyncCallback cb, Object state)

{

// 调用异步 Web 服务调用。

localhost.UserInfoQuery proxy

= new localhost.UserInfoQuery();

return proxy.BeginGetUserInfo("用户名",

cb,

proxy);

}

[WebMethod]

public int EndGetAge(IAsyncResult res)

{

localhost.UserInfoQuery proxy

= (localhost.UserInfoQuery)res.AsyncState;

int age = proxy.EndGetUserInfo(res).age;

// 在此对 Web 服务的结果进行其他

// 处理。

return age;

}

}

发生在 Web 方法中的最常见的 I/O 操作类型之一是对 SQL 数据库的调用。不幸的是,目前 Microsoft® ADO.NET 尚未定义一个完好的异步调用机制;而只是将 SQL 调用包装到异步委托调用中对提高效率没有什么帮助。虽然有时可以选择缓存结果,但是也应当考虑使用 Microsoft SQL Server 2000 Web Services Toolkit(英文)将您的数据库发布为 Web 服务。这样您就可以利用 .NET Framework 中的支持,异步调用 Web 服务以查询或更新数据库。

通过 Web 服务调用访问 SQL 时,需要注意众多的后端资源。如果您使用了 TCP 套接字与 Unix 计算机通信,或者通过专用的数据库驱动程序访问其他一些可用的 SQL 平台,甚至具有使用 DCOM 访问的资源,您都可以考