4

このQ & Aで、ASP.NET MVC を非同期処理に対応させる方法を 1 つ見つけました。しかし、私はそれを機能させることはできません。

基本的には、メソッドGetHttpHandlerを 1 つだけ持つ IRouteHandler の新しい実装を作成するという考え方です。GetHttpHandlerメソッドは、Begin/EndXXXX パターン API を持っているため、単に ではなく実装を返す必要がありますIHttpAsyncHandlerIHttpHandlerIHttpAsyncHandler

public class AsyncMvcRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new AsyncMvcHandler(requestContext);
    }

    class AsyncMvcHandler : IHttpAsyncHandler, IRequiresSessionState
    {
        public AsyncMvcHandler(RequestContext context)
        {
        }

        // IHttpHandler members
        public bool IsReusable { get { return false; } }
        public void ProcessRequest(HttpContext httpContext) { throw new NotImplementedException(); }

        // IHttpAsyncHandler members
        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {
            throw new NotImplementedException();
        }

        public void EndProcessRequest(IAsyncResult result)
        {
            throw new NotImplementedException();
        }
    }
}

次に、ファイル Global.asax.cs の RegisterRoutes メソッドで、このクラスAsyncMvcRouteHandlerを登録します。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new Route("{controller}/{action}/{id}", new AsyncMvcRouteHandler())
    {
        Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
    });
}

ProcessRequestBeginProcessRequestEndProcessRequestにブレークポイントを設定しました。ProcessRequestのみが実行されます。つまり、AsyncMvcHandlerはIHttpAsyncHandlerを実装していますが。ASP.NET MVC はそれを認識せず、単に実装として処理します。IHttpHandler

ASP.NET MVCでAsyncMvcHandlerをIHttpAsyncHandlerとして扱うようにして、非同期ページ処理を行うにはどうすればよいですか?

4

3 に答える 3

2

コードに何時間も悩まされた後、私は問題を発見しました。

Visual Studio 2008 で Ctrl+F5 を押すと、アプリケーション開発サーバーが起動し、IE がポップアップして " http://localhost:3573/ " にアクセスします。この場合、同期 API のProcessRequestが呼び出されます。スタックトレースはこんな感じ。

MyMvcApplication.DLL!MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.ProcessRequest(System.Web.HttpContext httpContext = {System.Web.HttpContext}) 行 59 C# System.Web.Mvc.dll!System.Web.Mvc.MvcHttpHandler.VerifyAndProcessRequest(System. Web.IHttpHandler httpHandler、System.Web.HttpContextBase httpContext) + 0x19 バイト
System.Web.Routing.dll!System.Web.Routing.UrlRoutingHandler.ProcessRequest(System.Web.HttpContextBase httpContext) + 0x66 バイト
System.Web.Routing.dll !System.Web.Routing.UrlRoutingHandler.ProcessRequest(System.Web.HttpContext httpContext) + 0x28 バイト
System.Web.Routing.dll!System.Web.Routing.UrlRoutingHandler.System.Web.IHttpHandler.ProcessRequest(System.Web.HttpContext ) context) + 0x8 バイト
MyMvcApplication.DLL!MyMvcApplication._Default.Page_Load(object sender = {ASP.default_aspx}, System.EventArgs e = {System.EventArgs}) 13 行目 + 0x1a バイト C#

しかし、IE で URL を「http://localhost:3573/whatever.mvc 」に変更すると、 BeginProcessRequestにヒットします。スタックトレースはこんな感じ。

MyMvcApplication.DLL!MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.BeginProcessRequest(System.Web.HttpContext コンテキスト = {System.Web.HttpContext}、System.AsyncCallback cb = {メソッド = {Void OnAsyncHandlerCompletion(System.IAsyncResult)}}、オブジェクト extraData = null ) 66 行目 C# System.Web.dll!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x249 バイト System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web. HttpApplication.IExecutionStep ステップ = {System.Web.HttpApplication.CallHandlerExecutionStep}、ref bool completedSynchronously = true) + 0x9c バイト
System.Web.dll!System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(System.Exception エラー) + 0x133 バイト
System.Web.dll!System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext コンテキスト、System.AsyncCallback cb、オブジェクト extraData) + 0x7c バイト
System.Web.dll!System.Web.HttpRuntime. ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x17c バイト System.Web.dll!System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest wr) + 0x63 バイト
System.Web. dll!System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest wr) + 0x47 バイト
WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Request.Process() + 0xf1 バイト WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Microsoft.VisualStudio.WebHost.Connection conn) + 0x4e バイト

「.mvc」サフィックスが付いた URL のみが非同期 API を呼び出すことができるようです。

于 2008-11-12T02:30:38.543 に答える
0

私は過去にこれをやろうとしましたが、ビューをレンダリングしてから、すべての非同期タスクを終了することができました。または、非同期タスクは終了しますが、ビューはレンダリングされません。

元の MVC コードに基づいて RouteCollectionExtensions を作成しました。私の AsyncMvcHandler には、ProcessMethod の空のメソッド (例外なし) がありました。

于 2008-11-10T19:07:18.953 に答える