سؤال

في هذا جواب السؤال, لقد وجدت طريقة واحدة لجعل ASP.NET MVC يدعم المعالجة غير المتزامنة.ومع ذلك، لا أستطيع أن أجعلها تعمل.

في الأساس، الفكرة هي إنشاء تطبيق جديد لـ IRouteHandler والذي له أسلوب واحد فقط GetHttpHandler.ال GetHttpHandler يجب أن يُرجع الأسلوب تطبيق IHttpAsyncHandler بدلاً من IHttpHandler فقط، لأن IHttpAsyncHandler لديه واجهة برمجة تطبيقات نمط Begin/EndXXXX.

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();
        }
    }
}

ثم، في أسلوب RegisterRoutes للملف Global.asax.cs، قم بتسجيل هذه الفئة AsyncMvcRouteHandler.سجلات الفراغ الثابتة العامة (RouteCollection Routes) {ROUTES.INTOREROUTE ("{Resource} .Axd/{*pathinfo}") ؛

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

قمت بتعيين نقطة التوقف عند طلب العملية, طلب بدء العملية و EndProcessRequest.فقط طلب العملية يتم تنفيذ.وبعبارة أخرى، على الرغم من AsyncMvcHandler ينفذ IHttpAsyncHandler.لا يعرف ASP.NET MVC ذلك ويتعامل معه فقط باعتباره تطبيق IHttpHandler.

كيفية جعل ASP.NET MVC يعامل AsyncMvcHandler مثل IHttpAsyncHandler حتى نتمكن من معالجة الصفحات غير المتزامنة؟

هل كانت مفيدة؟

المحلول 2

وبعد ساعات من المتاعب مع الكود، اكتشفت المشكلة.

في برنامج Visual Studio 2008 الخاص بي، عندما أضغط على Ctrl+F5، يتم تشغيل خادم تطوير التطبيقات ويظهر IE للوصول "http://localhost:3573/".في هذه الحالة، واجهة برمجة تطبيقات المزامنة طلب العملية يتم استدعاؤه.تتبع المكدس مثل هذا.

mymvcapplication.dll! mymvcapplication.asyncmvcroutehandler.asyncmvchandler.processrequest (system.web.httpcontext httpcontext = {system.web.httpcontext}) line 59 c. السعي (النظام. web.ihttphandler httphandler ، system.web.httpcontextbase httpcontext) + 0x19 bytes
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 Bytes
تطبيق MyMvc.DLL! MyMvcApplication._Default.Page_Load(كائن المرسل = {ASP.default_aspx} ، System.EventArgs e = {System.EventArgs}) السطر 13 0x1a بايت ج#

ومع ذلك، عندما أقوم بتغيير عنوان URL في IE ليكون "http://localhost:3573/whatever.mvc"، فإنه يضرب طلب بدء العملية.تتبع المكدس مثل هذا.

تطبيق MyMvc.DLL! MyMvcApplication.AsyncMvcRouteHandler.AsyncMvcHandler.BeginProcessRequest(System.Web.HttpContext السياق = {System.Web.HttpContext} ، System.AsyncCallback cb = {الطريقة = {باطل OnAsyncHandlerCompletion(System.IAsyncResult)}}, كائن إضافي البيانات = خالية) سطر 66 ج# 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}, المرجع بول مكتملمتزامن = صحيح) 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 بايت

يبدو أن عنوان url الذي يحتوي على اللاحقة ".mvc" فقط هو الذي يمكنه استدعاء واجهة برمجة التطبيقات غير المتزامنة.

نصائح أخرى

واجهت نفس المشكلة، لكنني وجدت أن السبب في ذلك هو معالج التقاط جميع المسارات الخاص بي:

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

تم التقاط الطلب، وليس المسار المخصص الذي أضفته والذي يتعامل مع معالج المسار غير المتزامن.ربما باستخدام .mvc في تعريف المسار المخصص الخاص بك، قمت بإنشاء تمييز بحيث تم استخدامه بدلاً من التقاط الكل المتزامن.

لقد حاولت القيام بذلك في الماضي، تمكنت إما من الحصول على العرض المطلوب ومن ثم ستنتهي جميع المهام غير المتزامنة.أو تنتهي المهام غير المتزامنة ولكن لن يتم عرض العرض.

لقد قمت بإنشاء RouteCollectionExtensions بناءً على رمز MVC الأصلي.في AsyncMvcHandler الخاص بي، كان لدي طريقة فارغة (بدون استثناء) لـ ProcessMethod.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top