0

صفحه انتظار بهتری بسازیم

 
amirpetrucci0261
amirpetrucci0261
کاربر طلایی1
تاریخ عضویت : تیر 1388 
تعداد پست ها : 27726
محل سکونت : http://zoomstar.ir/

صفحه انتظار بهتری بسازیم

تاکنون هر کسی که یک برنامه تحت وبی پیاده سازی کرده است که در آن انجام برخی از اعمال زمان بر است، حتما به این فکر افتاده که یک صفحه انتظار برای کاربر مخاطب خویش نمایش دهد. این صفحه میتواند این قابلیت را داشته باشد که از آنجایی که عموما کاربران در وب عجول هستند و حوصله صبر کردن را ندارند، با توجه به جنبه های بصری صفحه انتظار این موضوع رادرک کنند که براستی چیزی در حال اتفاق افتادن و پردازش شدن است و چنانچه آنها اندکی صبر کنند و منتظر بمانند قطعا نتیجه مورد نظر را خواهند دید

مشکل کجاست؟

از آنجایی که در آن واحد شما باید هم یک صفحه انتظار نمایش دهید و هم در پس پرده پردازشهای مورد نظر خود را انجام دهید، بسیاری از تکنیکهای برنامه نویسی تحت وب برای همزمانی در این حالت مناسب نیستند.از طرف دیگر باید این نکته را نیز در نظر داشت که در معماری کلاینت – سرور، سرور تنها زمانی پاسخ میدهد که کلاینت درخواستی داشته باشد. این بدان معناست که سرور نمیتواند به مرورگر سمت کلاینت بگوید چه زمانی پردازشش تمام شده است


یکی از گزینه هایی که مکررا اتفاق افتاده است فرستادن کاربر به یک صفحه انتظار است و پس از آن معمولا کاربر بلافاصله به آن صفحه ای که پردازش واقعی در آن انجام میگیرد فرستاده میشود.در این روش اگرچه ممکن است این مورد را رعایت کند که مرورگر تا زمانی که پردازش صفحه بعد تکمیل نشده است آن را نمایش ندهد، اما این کار دو عیب دارد. یکی اینکه اگر صفحه انتظار مورد نظر شما حاوی تصاویر متحرک باشد، به محض اینکه صفحه اصلی درخواست شد این تصاویر از تحرک باز می ایستند و دیگر اینکه مرورگر را مشغول به انجام کاری کرده ایم در حالی که عملا هیچ اتفاقی نیفتاده است.


راه حل دیگر این بوده است که صفحه انتظار را به صورت مکرر بازیابی یا reload کنیم و بررسی کنیم که آیا فرآبند پردازش مورد نظر خاتمه یافته است یا خیر. مسلما این کار هم جز این که سربار زیادی بر روی سیستم گذاشته و باعث اتلاف پهنای باند میشود نتیجه ای ندارد.

راه حل

با ظهور asp.net و توانایی آن در استفاده از .net framework برنامه نویسان وب نیز توانستند از مزایای برنامه نویسی غیرهمگام یا asynchronous در وب هم بهرمند گردند اما مشکل دیگر که همان معماری کلاینت سرور است و به سرور امکان نمیدهد تا کلاینت را باز فراخوانی یا call back کند چه؟ خوشبختانه ابزار جالبی به نام XmlHttpRequest میتواند پاسخگوی این نیاز ما باشد. میتوانیم با فراخوانی غیرهمگام متد مورد نظر و استفاده از XmlHttpRequest در پس زمینه میتوانیم صفحه انتظار بسیار هوشمند تری داشته باشیم.


برای حل این مشکل از 4 بخش زیر استفاده میکنیم:


• صفحه ورود- مسوول متوقف کردن رخداد غیرهمگام


• صفحه انتظار – مسوول ارزیابی کردن وضعیت پردازش مورد نظر و سرگرم کردن کاربر


• صفحه تست وضعیت – تنها مشخص میکند که آیا پردازش خاتمه یافته است یا خیر


• صفحه تایید – پس از خاتمه یافتن پردازش نشان داده خواهد شد

صفحه ورود

در این صفحه است که کاربر وارد شده و درخواست صفحه ای را میکند که پردازش طولانی مدت در آن قرار دارد. کد زیر از مدل برنامه نویسی غیرهمگام دات نت استفاده میکند. به این موضوع دقت کنید که نتیجه که به صورت یک شیء IAsyncResult است در متغیر Session ذخیره میگردد تا بعدا بتوانیم از آن استفاده کنیم

private void Button_Click()
{
IAsyncResult ar = DoSomethingAsync("abc");
Session["result"] = ar;
Response.Redirect("wait.aspx");
}
private IAsyncResult DoSomethingAsync(string someParameter)
{
DoSomethingDelegate doSomethingDelegate =
new DoSomethingDelegate(DoSomething);
IAsyncResult ar = doSomethingDelegate.BeginInvoke(someParameter,
ref confirmationNumber, new AsyncCallback(MyCallback), null);
return ar;
}
private delegate bool DoSomethingDelegate(string someParameter,
ref string confirmationNumber);
private void MyCallback(IAsyncResult ar)
{
AsyncResult aResult = (AsyncResult) ar;
DoSomethingDelegate doSomethingDelegate =
(DoSomethingDelegate) aResult.AsyncDelegate;
doSomethingDelegate.EndInvoke(ref confirmationNumber, ar);
}
private void DoSomething(string someParameter, ref string confirmationNumber)
{
Thread.Sleep(10000); //simulate a long process by waiting for ten seconds
confirmationNumber = "DONE!";
Session["confirmationNumber"] = confirmationNumber;
}

صفحه انتظار

این صفحه انتظار هیچ کد پشت صفحه ای لازم ندارد چرا که تنها از جاوا اسکریپت و XmlHttpRequest برای سرکشی به سرور و دیدن این که چه زمانی پردازش مورد نظر خاتمه یافته است استفاده میکند. این صفحه ابتدا یک درخواست سمت کلاینت از صفحه CheckStatus.aspx کرده و سپس طبق پاسخ دریافتی عمل میکند. همه این موارد بدون این که صفحه مجددا بازیابی شود انجام میگیرد. البته جالب است بدانید که این تکنیک وابسته به مرورگر خاصی نیست و با همه مرورگرها کار میکند.

<!--
var pollInterval = 1000;
var nextPageUrl = "confirmation.aspx";
var checkStatusUrl = "checkStatus.aspx";
var req;
// this tells the wait page to check the status every so often
window.setInterval("checkStatus()", pollInterval);
function checkStatus()
{
createRequester();
if(req != null)
{
req.onreadystatechange = process;
req.open("GET", checkStatusUrl, true);
req.send(null);
}
}
function process()
{
if(req.readyState == 4)
{
// only if "OK"
if (req.status == 200)
{
if(req.responseText == "1")
{
// a "1" means it is done, so here is where you redirect
// to the confirmation page
document.location.replace(nextPageUrl);
}
// NOTE: any status other than 200 or any response other than
// "1" require no action
}
}
}
/*
Note that this tries several methods of creating the XmlHttpRequest object,
depending on the browser in use. Also note that as of this writing, the
Opera browser does not support the XmlHttpRequest.
*/
function createRequester()
{
try
{
req = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(oc)
{
req = null;
}
}
if(!req && typeof XMLHttpRequest != "undefined")
{
req = new XMLHttpRequest();
}
return req;
}
//-->
</script>

به استفاده از document.location.replace(); زمانی که به صفحه تایید تغییر مکان داده میشود نیز دقت کنید. این کار باعث میشود تا صفحه انتظار از فهرست تاریخچه مرورگر حذف شده و دکمه Back در روند کار اخلالی ایجاد نکند

صفحه تست وضعیت یا CheckStatus

اين صفحه بسیار بسیار ساده است.تنها کاری که این صفحه انجام میدهد این است که IAsyncResult را چک میکند که آیا تکمیل شده است یا خیر. مقدار بازگشتی آن نیز بسته به شرایط گفته شده 1 یا 0 خواهد بود.

private void Page_Load(object sender, System.EventArgs e)
{
AsyncResult ar = (AsyncResult) Session["result"];
if(ar.IsCompleted)
Response.Write("1");
else
Response.Write("0");
Response.End();
}

صفحه تایید

زمانی که پردازش طولانی مدت خاتمه یافت، صفحه انتظار سیگنالی از صفحه تست وضعیت دریافت خواهد کرد که زمان تغییر مکان فرا رسیده است. سپس صفحه انتظار به صفحه تایید انتقال مکان خواهد داد و نتایج را به کاربر نمایش خواهد داد.

چهارشنبه 10 آذر 1389  5:35 AM
تشکرات از این پست
دسترسی سریع به انجمن ها