質問

この質問&回答、ASP.NET MVCが非同期処理をサポートする方法を見つけました。ただし、機能させることはできません。

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

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 = "" }),
        });
    }

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

ASP.NET MVCで AsyncMvcHandler IHttpAsyncHandler として処理して、非同期ページ処理を行えるようにする方法

役に立ちましたか?

解決 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     コンテキスト)+ 0x8バイト
      MyMvcApplication.DLL!MyMvcApplication._Default.Page_Load(オブジェクト     送信者= {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 = {メソッド=     {無効     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を呼び出すことができます。

他のヒント

同じ問題を抱えていましたが、それはすべてのルートハンドラをキャッチするためであることがわかりました。

routes.MapRoute(
    "Default",                                                  
    "{controller}/{action}",                           
    new { controller = "Home", action = "Index" }  
);

非同期ルートハンドラーを処理するために追加したカスタムルートではなく、リクエストを取得しました。おそらく、カスタムルート定義で.mvcを使用して、同期キャッチオールではなく使用されるように区別を作成しました。

過去にこれを実行しようとしましたが、ビューをレンダリングして取得すると、すべての非同期タスクが終了します。または、非同期タスクは終了しますが、ビューはレンダリングされません。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top