حل مشکل Controller Blocking در MVC
شنبه 22 آبان 1395در این مقاله قصد داریم مشکل Controller Blocking را در NET 4.5. و ASP.NET MVC با کمک نظریه هایی حل کنیم.
به تازگی در هنگام بروزرسانی یک پروژه MVC،چند مسئله نامنظم شروع به start میکنندکه کنترلر شامل فراخوانی نامعقول Controller blockingوapparent deadlockها میشودکه عموما به صورت غیر مفید برنامه را render میکردند.
آپدیت در دو فاز انجام میشود، اولین آن گسترش یک پروژه ساده ASP.NET MVC3 و دومین فاز آن بروز رسانی از .NET 4.0 به .NET 4.5 است، که به نظر میرسد همه چیز بد شکل است.
مشکل :
بعد از بروزرسانی به .NET 4.5،مرورگر Internet Explorer 9 و کمتر از آن شروع به مواجه شدن با مسائل عجیب راجع به فراخوانی های blocked برای کنترل هایی که در داخل برنامه است، میشود.مشکل معمولا زمانیکه یک درخواست ajax برای کنترلر ساخته میشود اتفاق می افتد ودر طول آن دوره یک درخواست اضافی ساخته شده برای کنترلر مشابه، که این باعث میشود که مرورگر برای 1 الی 2 دقیقه برای حل این مسائل و اجرای صف action ها قفل یا هنگ کند.
مثالی در قالب یک سناریو
در زیر مجموعه ای از اقدامات که یک کاربر شاید آن ها را انجام دهد و باید به عنوان یک راهنما برای تعیین این که آیا این مشکل همان مشکلی است که شما را تحت تاثیر قرا داده است به کار برد.
• کاربر بر روی یک لینک کلیک میکند که در آن به طور موقت یک مقدار در ViewData برای دسترسی به درخواست بعدی ذخیره شده است.
• یک Redirect رخ میدهد و کنترلر دیگری در دسترس است و بعد از عملیات load فراخوانی ajax ساخته میشود.
• در طول این فراخوانی ajax ، که مقدار ViewData در دسترس است.یک فراخوان به سرعت ساخته میشود. بعد از کلیک بر روی این لینک ، deadlock رخ میدهد و مرورگر unresponsive میشود.
یا
• فراخوانی با موفقیت انجام میشود در طول آن هیج وقفه ای توسط درخواست های دیگر صورت نمیپذیرد. اما تلاش برای انجام مراحل قبل دوباره fail میشود.
هر صفحه در question ،که دلیل این مشکلات بود یکی از دو کار زیر را انجام میدهد
• View شامل یک گرید jQuery است که با یک AJAX فراخوانی میشود برای گرفتن محتویات گرید بر page loading .
• کنترلر Action معمولا وظیفه اش خواندن یک آیتم از ViewData در داخل آن Action ها است.
یک بررسی:
پس از نگاه کردن به تمام چیزهایی که میتواند دلیل این مساله باشد از قبیل فراخوانی AJAX های خودمان، تنظیمات SessionState برای برنامه، Caching،ذخیره موقت چیز دیگری به نظر نمیرسد که این مشکل را ایجاد کند.
ما تلاش کردیم از Fiddler استفاده کنیم هرچند که به عنوان یک ترافیک چیزی برای نمایش به ما نداشت به ما اجازه نداد.
ابزار توسعه دهنده و Fiddler هر دو آن ها فراخوانی ajax را نمایش میدهد و یک Action کنترلر میسازد، که شامل یک breakpoint است ،هرچند که breakpoint هیچ وقت hit نمیشود.
در اینجا ما برای fixe کردن چند تا از آنها میپردازیم.
• فراخوانی AJAX
ما امیدواریم که توسط قرار دادن مقدار cache به false مطمئن میشویم که درخواست های ajax ، کش (cache) نشده اند
همچنین ما سعی میکنیم که از خصوصیت timeout برای وقتی که درخواست timeOut میشود اثرش block شود.
// Disabled caching and forced an explicit timeout on the calls $.ajaxOptions({ cache: false, timeout: 1000 });
• SessionState
حقیقت اینکه کنترل ها در داخل برنامه یکدیگر را بلاک میکردند ما را وادار به این کرد که فکر کنیم مقصر SessionState هستند و به وسیله ست کردن آنها به ReadOnly یا Disable این مشکل را حل کردیم.
[Authorize] [SessionState(SessionStateBehavior.ReadOnly)] public class MyController : ApplicationController
دسترسی به ذخیره های موقتی
ما فکر میکنیم که این مسئله به دلیل استفاده از ذخیره های موقت در داخل نرم افزار باشد بنابراین ما سعی میکنیم ViewData را با Session برای ذخیره سازی موقت مقادیری که فرستاده میشوند جایگزین کنیم اما باز هم با شکست روبه رو میشویم.
// Trying all three of these, but still met with failure ViewData["YourKey"] = yourValue; Session["YourKey"] = yourValue; TempData["YourKey"] = yourValue;
هیچ کدام از این ها راه حل مشکل را نشان نمیدهند بنابراین ما فکر کردیم که ، مستقیما IIS را بررسی کنیم تا متوجه شویم که آیا مشکل در سطح IIS رخ داده یا خیر.
سرانجام؛ چند راه حل کلاسیک
تغییر حالت برنامه در داخل نرم افزار Pool در تنظیمات IIS از مجتمع به کلاسیک.
اگر شما با مسئله های عجیب و سخت مواجه شدید سعی کنید حالت برنامه را در داخل نرم افزار Pool در تنظیمات IIS به کلاسیک تبدیل کنید.
ما کاملا مطمئن نیستیم که همه ی جزئیات که IE9, .NET4.5 و ajax بخواهند که به خوبی با دیگری کار کنند.
این مسئله میتواند در حقیقت یک باگ در SessionState باشد و اینکه چگونه Internet Explorer 9 با ماشین های بروزرسانی شده برای پیاده سازی فراخوانی های همگون که به تازگی در NET 4.5 آمده است در تعامل است.
بروزرسانی با بهبود بخشیدن به مشکل
ما قادر به محدود کردن بیشتر خصوصیت uploadReadAhead در web.config هستیم.
<system.webServer> <serverRuntime uploadReadAheadSize="0" /> </system.webServer></pre>
شما نیاز به فعال سازی این property دارید.
<section name="serverRuntime" overrideModeDefault="Allow" />
آموزش asp.net mvc
- ASP.net MVC
- 1k بازدید
- 1 تشکر