| [WebService] public class SyncWebService : System.Web.Services.WebService { [WebMethod] public string LengthyProcedure(int milliseconds) { System.Threading.Thread.Sleep(milliseconds); return "成功"; } } |
[WebService] public class AsyncWebService : System.Web.Services.WebService { public delegate string LengthyProcedureAsyncStub( int milliseconds); public string LengthyProcedure(int milliseconds) { System.Threading.Thread.Sleep(milliseconds); return "成功"; } public class MyState { public object previousState; public LengthyProcedureAsyncStub asyncStub; } [ System.Web.Services.WebMethod ] public IAsyncResult BeginLengthyProcedure(int milliseconds, AsyncCallback cb, object s) { LengthyProcedureAsyncStub stub = new LengthyProcedureAsyncStub(LengthyProcedure); MyState ms = new MyState(); ms.previousState = s; ms.asyncStub = stub; return stub.BeginInvoke(milliseconds, cb, ms); } [ System.Web.Services.WebMethod ] public string EndLengthyProcedure(IAsyncResult call) { MyState ms = (MyState)call.AsyncState; return ms.asyncStub.EndInvoke(call); } } |
何时采用异步 Web 方法
在确定是否适合在您的应用程序中采用异步 Web 方法时,有几个问题需要考虑。首先,调用的 BeginXXX 函数必须返回一个 IAsyncResult 接口。IAsyncResult 是从多个异步 I/O 操作返回的,这些操作包括访问数据流、进行 Microsoft? Windows? 套接字调用、执行文件 I/O、与其他硬件设备交互、调用异步方法,当然也包括调用其他 Web 服务。您可以从这些异步操作中得到 IAsyncResult,以便从 BeginXXX 函数返回它。您也可以创建自己的类以实现 IAsyncResult 接口,但随后可能需要以某种方式包装前面提到的某个 I/O 操作。
对于前面提到的大多数异步操作,使用异步 Web 方法包装后端异步调用很有意义,可以使 Web 服务代码更有效。但使用委托进行异步方法调用时除外。委托会导致异步方法调用占用进程线程池中的某个线程。不幸的是,ASMX 处理程序为进入的请求提供服务时同样要使用这些线程。所以与对硬件或网络资源执行真正 I/O 操作的调用不同,使用委托的异步方法调用在执行时仍将占用其中一个进程线程。您也可以占用原来的线程,同步运行您的 Web 方法。