حل مشکل Controller Blocking در MVC

شنبه 22 آبان 1395

در این مقاله قصد داریم مشکل Controller Blocking را در NET 4.5. و ASP.NET MVC با کمک نظریه هایی حل کنیم.

حل مشکل Controller Blocking در 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

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید