ASMX相当于RegisterAsyncTask [英] ASMX equivalent of RegisterAsyncTask

查看:86
本文介绍了ASMX相当于RegisterAsyncTask的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When an ASPX page needs to make a call to a potentially long-running operation (lengthy DB query, call to a remote webservice, etc.), I use RegisterAsyncTask, so the IIS worker thread is returned to the pool, rather than being tied up for the duration of the long-running operation.

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

However ASMX webservices don't have a RegisterAsyncTask function. When an ASMX webservice needs to call a potentially long-running operation, how can I implement the same behavior as RegisterAsyncTask?

注意:ASMX Web服务是作为脚本服务实现的:将json返回到直接jQuery/ajax调用.因此,我不能使用 MSDN ,因为它可以在生成的客户端存根中实现异步行为(当直接通过ajax调用Web服务时不使用该行为).

Note: the ASMX webservice is implemented as a script-service: returning json to a direct jQuery/ajax call. Therefore, I cannot use the "BeginXXX" approach described by MSDN, since that implements the asynchronous behavior within the generated client-stub (which isn't used when calling the webservice directly via ajax).

EDIT :添加源代码:实现了John的答案中列出的BeginXXX/EndXXX方法.同步鹦鹉"功能可以正常工作.但是异步的"SlowParrot"函数给出了一个内部服务器错误:未知的Web方法SlowParrot"

EDIT: Adding source code: implemented the BeginXXX/EndXXX approach listed in John's answer. The synchronous "Parrot" function works fine. But the asynchronous "SlowParrot" function gives an internal server error: "Unknown web method SlowParrot"

WebService1.asmx:

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:

WebForm1.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <script type="text/javascript" src="scripts/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="scripts/json2.js"></script>
    <script type="text/javascript">
        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);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="myDiv"></div>
    <p><a href="javascript: showHelloWorld();">show hello world</a> | <a href="javascript: showSomethingElse();">show something else</a></p>
    </form>
</body>
</html>

推荐答案

您需要做出明确的决定,在哪里进行异步调用,并确切地知道在哪里运行以及生成了哪些代码.没有魔术:-)

You need to make clear decision where do you want async invocation to happen and know exactly what runs where and which code gets generated. There's no such thing as magic :-)

只有带有[WebMethod]的函数才能作为Web方法可见-具有您为其指定的确切名称.因此,至少您必须调用BeginSlowParrot和EndSlowParot,但这对您无济于事,因为调用第一个将转到Web场中的服务器Foo1,第二个将到达服务器Foo2,更不用说即使使用同一台服务器(例如粘性IP),您必须测试IAsyncResult背后的实际对象是否可以从JSON序列化中重播(可以说,与XML相比,JSON的类型差). 即使是这样,它仍然仅在信号机服务器中有效.

Only functions with [WebMethod] are ever visible as web methods - with the exact names you gave them. So at the very least you'd have to invoke BeginSlowParrot and EndSlowParot but that wouldn't help you much since calling 1st will go to server Foo1 and the 2nd to server Foo2 in a web farm, not to mention that even with the same server (say sticky IP) you'd have to test if the actual object behind IAsyncResult is replayable from a JSON serialization (JSON is type-poor compared to XML so to speak). Even if it is, that still only works in a signle server scenario.

.NET库知道如何通过在WSDL中看到代理方法来自动生成代理方法(当它们在WSDL中看到它们时),但是仍然是2种实际的Web方法-从IE浏览器访问WebService1.asmx?WDSL,您将确切地看到声明了什么

.NET libs know how to autogen proxy methods by following Begin/End as naming convention when they see them in a WSDL but it's still 2 actual web methods - do WebService1.asmx?WDSL from IE and you'see exactly what's declared.

如果要从多个线程上的客户端异步调用某些内容(它们在IE中而不是在服务器中),则需要额外的JavaScript代码来进行操作-网络方法本身保持原样.您将需要仅在客户端上处理第二个隐藏呼叫的第二个DIV,以及仅在第三个和第四个呼叫处理的第三个-所需的每种其他类型的异步交互.

If you want to invoke something asynchronously from the client on multiple threads (they are in IE not the server) then you need extra JavaScript code to do that - web methods themselves remain as they were. You'll need 2nd hidden DIV on the client that will handle only these slow calls and the 3rd and 4th - one for every additional kind of async interaction you want.

所以我最好的猜测是,您首先需要确认确实对2个$ ajax(...)调用进行了序列化(您需要2个缓慢且不同的Web方法来确认-每个方法都返回不同的值),如果是,则您需要深入研究包含$ ajax的包含的.js,并查看发生了什么).它可能会保护自己免受ppl尝试在浏览器中执行完整的miltithreading,然后抱怨其数据已损坏:-)

So my best guess is that you first need to confirm that 2 $ajax(...) calls are serialized indeed (you need 2 slow and different web methods to confirm that - each returning different value) and if so, you need to dig into included .js that contains $ajax and see what's going on there). It might be protecting itself from ppl trying to do full miltithreading in a browser and then complain that their data got damaged :-)

如果您要在服务器上保持异步状态-该异步消息必须保留在该服务器上-您的客户端仍必须等待其执行的一次调用的响应,但是Web方法代码可以产生5个异步调用来运行它的操作,请等待让他们完成,收集和合并结果,然后将其发回.

If you want something async on the server - that has to remain on that server - your client will still have to wait the response of one invocation it did but the web method code can spawn 5 async calls to run it's stuff, wait for them to finish, collect and merge results and then send them back.

哦,如果您想从ASPX页面中复制某些内容,则需要挖掘(在浏览器中)为其生成的源代码,并且还知道C#代码中的哪些内容可以生成什么内容. ASP.NET尽力将其隐藏起来,并尽可能地使您感到困惑.它是为讨厌客户端服务器编程并希望假装自己在编写本地Windows应用程序的ppl完成的.因此,无论您看到什么,都拥有完全私有的API,并且您必须查看生成的页面(标签和js代码以及包含在内),以查看发生了什么.

Oh and if you want to copy something from an ASPX page you need to dig through the source generated for it (in a browser) and also know which things in your C# code generte what. ASP.NET tries very hard to hide that from you and confuse you as much as possible. It was done for ppl who hate client-server programming and want to pretend they are writing a local Windows app. So whatever you see there is totally private API and you have to look at generated page (tags and js code and includes) in you want to see what's going on.

这篇关于ASMX相当于RegisterAsyncTask的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆