ASMX相当于RegisterAsyncTask

当ASPX页面需要调用可能长时间运行的操作(冗长的数据库查询,调用远程Web服务等)时,我使用RegisterAsyncTask,因此IIS工作线程被返回到池中,而不是被绑定在长时间运行的持续时间内。

但是,ASMX Web服务没有RegisterAsyncTaskfunction。 当ASMX Web服务需要调用可能长时间运行的操作时,如何实现与RegisterAsyncTask相同的行为?

注意:ASMX webservice是作为脚本服务实现的:将json返回到直接的jQuery / ajax调用。 因此,我不能使用MSDN描述的“BeginXXX”方法,因为它实现了生成的客户端存根中的异步行为(在通过ajax直接调用webservice时不使用)。

编辑 :添加源代码:实现了John的答案中列出的BeginXXX / EndXXX方法。 同步“Parrot”function正常工作。 但异步“SlowParrot”函数给出了内部服务器错误:“未知的Web方法SlowParrot”

WebService1.asmx:

// Test class implemented according to: http://msdn.microsoft.com/en-us/library/aa480516.aspx [WebService] [ScriptService] public class WebService1 : WebService { // A normal, synchronous webMethod, to prove the overall webservice is working. [WebMethod(EnableSession = true)] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public string Parrot(string key) { return key; } // Artificially-slow function (uses Thread.Sleep). public string SleepyParrot(string key) { Thread.Sleep(10000); return key; } // Delegate matching our slow-running function. public delegate string SleepyParrotStub(string key); // State object to hold the delegate. public class MyState { public SleepyParrotStub Stub; } // Asynchronous web method, which should be accessible via: "Webservice1.asmx/SlowParrot". [WebMethod(EnableSession = true)] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public IAsyncResult BeginSlowParrot(string key, AsyncCallback callback, object asyncState) { SleepyParrotStub stub = new SleepyParrotStub(SleepyParrot); MyState ms = new MyState(); ms.Stub = stub; return stub.BeginInvoke(key, callback, ms); } // Asynchronous web method, which should be accessible via: "Webservice1.asmx/SlowParrot". [WebMethod(EnableSession = true)] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public string EndSlowParrot(IAsyncResult result) { MyState ms = (MyState)result.AsyncState; return ms.Stub.EndInvoke(result); } } 

WebForm1.aspx的:

        function showHelloWorld() { $.ajax({ type: "POST", url: "WebService1.asmx/Parrot", contentType: "application/json; charset=utf-8", dataType: "json", data: '{"key":"Hello World"}', success: myCallback, error: function(response) { alert(response.statusText); } }); } function showSomethingElse() { $.ajax({ type: "POST", url: "WebService1.asmx/SlowParrot", contentType: "application/json; charset=utf-8", dataType: "json", data: '{"key":"something else"}', success: myCallback, error: function(response) { alert(response.statusText); } }); } function myCallback(response) { $("#myDiv").html(response.d); }    

show hello world | show something else

您需要明确决定在哪里进行异步调用,并确切知道运行的位置和生成的代码。 没有魔法这样的东西:-)

只有[WebMethod]的函数才能作为Web方法显示 – 具有您给出的确切名称。 所以至少你必须调用BeginSlowParrot和EndSlowParot,但这对你来说没什么用,因为调用1st会转到服务器Foo1而第二个转到服务器场Foo2,更不用说即使使用相同的服务器也是如此(比如粘性IP)你必须测试IAsyncResult背后的实际对象是否可以从JSON序列化中重放(JSON与XML相比可以说是类型差)。 即使是这样,它仍然只适用于单点服务器场景。

.NET库知道如何通过在WSDL中看到它们时将Begin / End作为命名约定来自动代理方法,但它仍然是2个实际的Web方法 – 从IE做WebService1.asmx?WDSL并且你看到了所声明的内容。

如果你想在多个线程上从客户端异步调用某些东西(它们在IE而不是服务器中),那么你需要额外的JavaScript代码才能做到这一点 – 网络方法本身保持不变。 您将需要客户端上的第二个隐藏DIV,它只处理这些慢速调用以及第三个和第四个 – 一个用于您想要的每种其他类型的异步交互。

所以我最好的猜测是你首先需要确认2 $ ajax(…)调用确实是序列化的(你需要2个慢速和不同的web方法来确认 – 每个都返回不同的值)如果是这样,你需要挖掘包含$ ajax的包含.js,看看那里发生了什么)。 它可能是保护自己免受ppl尝试在浏览器中进行完全miltithreading然后抱怨他们的数据被损坏:-)

如果你想在服务器上保持异步 – 必须保留在该服务器上 – 你的客户端仍然必须等待它所做的一次调用的响应,但是web方法代码可以产生5个异步调用来运行它的东西,等待它们完成,收集和合并结果,然后将其发回。

哦,如果你想从ASPX页面复制一些内容,你需要深入研究为它生成的源代码(在浏览器中),并且知道你的C#代码中的哪些东西是什么。 ASP.NET非常努力地将这些内容隐藏起来并尽可能地让您感到困惑。 它是为那些讨厌客户端 – 服务器编程并希望假装他们正在编写本地Windows应用程序的人而完成的。 所以无论你看到什么都有完全私有的API,你必须查看生成的页面(标签和js代码和包含),你想看看发生了什么。

请参阅MSDN文档中的“ 异步XML Web服务方法 ”。