PDA

View Full Version : گفتگو و آموزش در مورد asp.net Caching



golagha_program
دوشنبه 13 مهر 1388, 09:24 صبح
سلام.
بحثي رو كه مي خوام شروع كنم راجع به كش كردن اطلاعات در asp.net.

كش كردن يكي از قدرت مندترين امكانات موجود در asp است.شما مي توانيد ابتدا اطلاعات را از بانك اطلاعاتي بگيريد و در كش قرار دهيد و در مراجعات بعدي اطلاعات كش را بجاي بانك اطلاعاتي بخوانيد. خوب همه موافقيد كه چقدر كارايي و سرعت كار بالا مي رود .چيز جالبي كه بايد راجع به كش بگم اينه كه كش thread safe است و امنيت محتويات داخل كش بالاست و در هنگام خواندن و نوشتن روي كش قفل گذاري انجام مي شه.
خوب حالا بريم يك سري كد بزنيم ببينيم چجوري مي شه كشينگ رو تعريف كرد و چجور ازش استفاده كرد.


public static class Caching
{


public static Cache Cache
{
get { return HttpContext.Current.Cache; }
}

public static void RefreshCacheData(string key, object obj)
{
Caching.Cache.Remove(key);
Caching.Cache.Insert(key, obj, null, DateTime.Now.AddHours(2), TimeSpan.Zero);
}

public static void CacheData(string key, object obj)
{

Caching.Cache.Insert(key, obj, null, DateTime.Now.AddHours(2), TimeSpan.Zero);
}
}

خوب نكته مهم اينجا اين key هستش.كه روش هاي مختلفي براي تعريف اين كليد وجود داره شما مي تونيد نام جدول توي بانك رو بعنوان كليد تعريف كنيد استفاده از كلاس بالا.


string key = "Product";
Caching.CacheData(key,objProduct);


كه اين objproduct از كلاس product پر شده كه فكر كنم طريقه پر كردنش راحت باشد .
حالا ما كش رو داريم بايد اول تست كنيم اگر اطلاعات توش هست محتوياتش رو بخونيم اگر نيست بريم از بانك اطلاعاتي بخونيم و كش رو نيز پر كنيم.


if(Caching.Cache["Product"] != null)
{
شي product رو از كش پر كن
}
else

{
برو از بانك اطلاعات رو بخون
Caching.CacheData(key,objProduct);
}


خوب ببخشيد كه كداي من خيلي خلاصه هستش من قصدم خوندن و نوشتن از بانك اطلاعاتي نيست اطلاعاتي در مورد كش دارم ميدم.
///////////////////////////
حالا فرض كنيد چطور مي شه اطلاعات كش رو بروز كرد شما اگر محصول جديدي رو وارد كنيد يا بروز كنيد يا حذف كنيد ديگه داده هاي كش معتبر نيست. جه كار بايد كرد.
خوب اين كليدي كه تعريف كرديم اينجا بدرد مي خوره.
من يك تابع مي نويسيم كه تمام وابستگي ها رو از بسين ببره منظور از وابستگي:
شما يك كليد داريد كه نام Product و ليستي از محصولات توي كش
شما كليد ديگري داريد كه به نام Product+Productidكه يك محصول خاص در كش اين دو تا كليد در product مشترك هستن حالا اگر اطلاعات Product +productid حذف يا تغير كنه كش اول كه ليست محصول است اونم نا معتبر مي شه.پس بايد كش هاي وابسته رو خالي كرد و دوباره پر كرد اينم تابعش


public void DeletePrefix(string prefix)
{
prefix = prefix.ToLower();
List<string> itemsToRemove = new List<string>();

IDictionaryEnumerator enumerator = Cache.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().ToLower().StartsWith(pr efix))
itemsToRemove.Add(enumerator.Key.ToString());
}

foreach (string itemToRemove in itemsToRemove)
Cache.Remove(itemToRemove);
}

خوب فكر مي كنم كد راحتي باشه و نياز به توضيح نداره.
-----------------------------------------------------------------------
حالا مي ريم سر يه موضوع جالب و قشنگ گفتم كش thread safe ولي وقتي اطلاعات و ازش خارج كنيم ديگه اون اطلاعات safe نيستن و خودمون بايد قفل گذاري كنيم.منظورم اينه كه تا وقتي ليستي از محصولات در كش داريم اين ليست امنيت داره ولي تا از كش خارج بشه براي تغييرات ديگر امن نيست.
بايد چي كار كرد.
من اين كلاس رو براي كشينگ پيشنهاد مي كنم


public class SynchronizedCache
{
private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();

public Cache Cache
{
get { return HttpContext.Current.Cache; }
}

public object Read(string key)
{
cacheLock.EnterReadLock();
try
{
return Cache.Get(key);
}
finally
{
cacheLock.ExitReadLock();
}
}

public object ReadWithOutLock(string key)
{
return Cache.Get(key);
}

public void Add(string key, object value)
{
cacheLock.EnterWriteLock();
try
{
Cache.Insert(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
}

public void AddWithOutLock(string key, object value)
{
Cache.Remove(key);
Cache.Insert(key, value);
}

public bool AddWithTimeout(string key, object value, int timeout)
{
if (cacheLock.TryEnterWriteLock(timeout))
{
try
{
Cache.Insert(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
return true;
}
else
{
return false;
}
}


public AddOrUpdateStatus AddOrUpdate(string key, object value)
{
cacheLock.EnterUpgradeableReadLock();
try
{
if (value==Cache.Get(key))
{
return AddOrUpdateStatus.Unchanged;
}
else
{
cacheLock.EnterWriteLock();
try
{
Delete(key);
Cache.Insert(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
return AddOrUpdateStatus.Updated;
}
}
finally
{
cacheLock.ExitUpgradeableReadLock();
}
}


public void Delete(string key)
{
cacheLock.EnterWriteLock();
try
{
Cache.Remove(key);
}
finally
{
cacheLock.ExitWriteLock();
}
}

public void DeletePrefix(string prefix)
{
prefix = prefix.ToLower();
List<string> itemsToRemove = new List<string>();

IDictionaryEnumerator enumerator = Cache.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().ToLower().StartsWith(pr efix))
itemsToRemove.Add(enumerator.Key.ToString());
}

foreach (string itemToRemove in itemsToRemove)
Cache.Remove(itemToRemove);
}

public enum AddOrUpdateStatus
{
Added,
Updated,
Unchanged
}

}

كه قفل گذاري توسط خودمون كنترل مي شه و همزماني خوبي اعمال مي شه.كد بالا از System.Threading
داره استفاده مي كنه و بروي خواندن و نوشتن قفل مي زاره.
-----------------------------------------------------------------------------------------
حالا من در مورد كش و همزماني در كشينگ اطلاعاتي دادم كه اميدوارم مفيد باشه حالا مي تونيم وارد جزئيات بشيم و گفتگو كنيم.
با تشكر.
------------------------------------------------------

Saber_Fatholahi
سه شنبه 28 مهر 1388, 09:32 صبح
با تشکر دوست من اطلاعات جالی دادید منم از کش استفاده می کنم تقریبا به همین صورت اما متاسفانه بعضی مواقع صفحاتی از سایت مخصوصا که با دیتابیس کار میکنن خطای مبنی بر پیدا نشدن ریسورس میدن که به نظرم از کشه
برنامه نویسی من سه لایه هست
نمونه اون سایت خودمه که بعضی مواقع این خطارو میده

alireza_s_84
سه شنبه 28 مهر 1388, 11:09 صبح
با سلام خدمت دوستان عزیز و تشکر از جناب golagha_program (http://barnamenevis.org/forum/member.php?u=18577) در ادامه مطالب زیباشون من پست هایی رو میدم تا نهان گذاری(Caching) رو کامل توی این تاپیک توضیح بدم.
نهان گذاری چیست؟ تکنیکی که وقتا اطلاعات ارزشمند رو در حافظه سرور ذخیره میکنه تا در دفعات بعدی از آنها استفاده کنیم. ضمنا مشکلاتی چون استفاده از Application و Session رو هم نداره.
دیر زمانی بود که برنامه نویسان Asp کلاسیک از شی Application برای نگهداری اشیا عمومی استفاده میکردن. که یکی از معایب بزرگش فقدان حافظه بود . در نهان گذاری هم از حافظه ی سرور برای نگهداری داده ها و اشیا استفاده میکنیم اما با روش بهینه تری.
از نهان گذاری اغلب برای ذخیره سازی اطلاعات بازیابی شده از دیتابیس ها استفاده میشه. دلیل خوبی هم برای اینکار وجود داره . چون اتصال به دیتابیس ها کاری بسیار زمان بر و سنگینه. زمان برداشت داده ها از Cache مثل برق صورت میگیره اما محدودیت زمانی اتصال به دیتابیس ها + سرعت پایین + محدودیت اتصالاتی که میتونه از یک دیتابیس استفاده کنه همه و همه دلایل موجهی برای استفاده از نهان گذاریه.
البته ذخیره کردن اطلاعات توی حافظه هم هم همیشه ایده خوبی نیست . چون حافظه سرور محدوده و اگه بخوایم بطور نامعقول از کشینگ استفاده کنیم با کاهش چشمگیر سرعت مواجه میشیم.(یک مثال نامعقول از استفاده کشینگ بازیابی لیست تمامی محصولات فروشگاه و ذخیره کردن اونها در حافظه ست در ابتدا ممکنه تعداد محصولات کم باشه اما شما تصور کنید یک میلیون رکورد تو حافظه ه حالی به سرور میده مطمئنا رو دل میکنه:چشمک:)
حالا با این همه مقدمه چینی یه سوال پیش میاد که کی از نهانگذاری استفاده کنیم؟؟؟
شما میتونید با انتخاب بهترین زمان نگهداری داده ها در کشینگ اطلاعاتی رو که استفاده از آنها عمومی و به مراتب زیاده رو ذخیره کنید. هرچند استفاده از کشینگ هرگاه با کمبود حافظه مواجه بشه بدون هیچ تعارفی کش رو خالی میکنه و منتظر اجازه شما نمیشه(بله این در ظرهر بده اما قدرت کشینگ به همین خاطره)
برای همین همیشه قبل از استفاده از کشینگ باید محتویات کش رو چک کنیم که خالی نباشه.
نکته: هرگاه منابع حافظه در سرور کم شود اقدام به حذف اقلامی از کشینگ میکند.:افسرده:
در استفاده از کش دو مفهوم داریم: 1- اجرا 2-قیاس پذیری
چون خیلی مفصل و یه کم پیچیده هستن (من که اصلا علاقه ای به دونستنشون ندارم شاید تو دانشگاه به زور استاد دنبالشون برید) توضیح نمیدم
میرم سر مبحث اصلیمون که انواع نهانگذاری رو میخوام توضیح بدم:
1- نهانگذاری برونداد
2- نهانگذاری داده ها
در واقع ما فقط همین دو نوع نهانگذاری رو داریم و در یک برنامه واقعی باید از هر دو نوع استفاده کنیم چون این دو مکمل هم هستن(مثل زن و شوهر) ضمنا در مورد نر یا ماده بودن هیچکدومشون هم اطلاعی ندارم.:بامزه:
نهانگذاری برونداد(بابا انگلیسیش قشنگتره Output Caching): این نهانگذاری ساده ترین روش نهانگذاریه و نسخه ای از صفحه HTML رو که داره میره سمت کلاینت رو ذخیره میکنه. از مزایاش هم اینه که در دفعات بعدی هیچ کدی اجرا نمیشه و صفحه ذخیره شده بازپس داده میشه(خیلی عالیه مگه نه) مثلا در صفحاتی که محتواشون تقریبا ثابته و فقط خیلی جزیی تغییر میکنه میتونید از این روش استفاده کنید. نمونه هم واسه دانشجویان عزیزی که میخوان بدونن مثلا چه صفحاتی(آخ چقدر از این جور دانشجوها بدم میاد اینقدر سوال میپرسن تا یه جایی که بلد نیستی گیر میندازنت کلی بهت میخندن)
یک نمونه ش صفحات تماس با ما (Contact) که توی اونها همه چیز ثابته فقط ممکنه یه تاریخ عوض بشه.
البته بازهم بگم نیاید صفحه ای که کاملا ثابته رو با Aspx طراحی کنید و بعد کش کنید(کاری که برنامه نویسای خیلی خیلی باهوش میکنن) با HTML طراحی کنید بهتره.
نهانگذاری داده ها هم بصورت دستی صورت میگیره . برای استفاده از این نهانگذاری اطلاعات مهمی رو که بازیابی و ساختنشون زمانبره (مثلا دیتاتیبل ها + دیتاست ها توی معماری های من در آوردی 3 الی 1000 لایه) (کسی ایراد نگیره گفتم معماری های من در آوردی :خجالت:)
این روش هم بسیار خوبه و سرعت و قیاس پذیری از مزایاشه.(نمونه شو هم بالا دیدن که دوست عزیزمون از این روش استفاده کرده بود)
دو نوع تخصصی از ساختار هم برای این دو نوع نهانگذاری وجود داره:
نهانگذاری قسمتی از صفحه (که نوع تخصصی نهانگذاری برونداده و به جای کشینگ کل صفحه قسمتی از کد HTML رو کش میکنه به این ترتیب در بارهای بعدی کد صفحه اجرا میشه اما قسمت ذخیره شده اجرا نمیشه)
نهانگذاری منبع داده ها:
این نوع نهانگذاری از همون نهانگذاری داده ها منشا میگیره اما دیگه دستی نیست یعنی نیازی نیست کدنویسی کنید فقط چند تا خاصیت تنظیم میکنید و موارد استفاده ش هم توی SqlDataSource + ObjectDataSource + AccessDataSource و XMLDataSource هاست.

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


استفاده از نهانگذاری برونداد
استفاده از نهانگذاری در سمت سرور
نهانگذاری و رشته استعلام
نهانگذاری به کمک پارامترهای خاص رشته استعلام
مثالی از نهانگذاری چندگانه

تا جلسه آینده همتون موفق و پیروز باشید

hashemi85sep
سه شنبه 28 مهر 1388, 16:34 عصر
با سلام خدمت اساتید گرامی
یه سوال برام پیش اومد
اون اینه که از cashe میشه موقعی که کاربر به سات login میشه استفادکرد و تمامی مشخصاتش رو توی cashe قرار داد و ازش تاموقعی که از سایت خارج نشده استفاده کرد ؟؟؟

با تشکر...

persianspam
سه شنبه 28 مهر 1388, 17:46 عصر
با تشکر دوست از شما اساتید
در صورت امکان یک نمونه پروژه وب (Solution) از این مبحث ساخته و در اختیار ما کاربران مبتدی قرار دهید
با تشکر

persianspam
سه شنبه 28 مهر 1388, 17:51 عصر
فرضا" ما یک دیتاست داریم که از یک سری دیتا از دیتابیس پر شده.
حالا چگونه میتوان این دیتاست را داخل یک کلید پر کرد و چطوری میتوان دوباره آن کلید را ریخت داخل دیتاست ؟

alireza_s_84
سه شنبه 28 مهر 1388, 20:24 عصر
با سلام خدمت اساتید گرامی
یه سوال برام پیش اومد
اون اینه که از cashe میشه موقعی که کاربر به سات login میشه استفادکرد و تمامی مشخصاتش رو توی cashe قرار داد و ازش تاموقعی که از سایت خارج نشده استفاده کرد ؟؟؟

با تشکر...
سلام دوست عزیز:
Cache بین تمام کاربران یک وب سایت عمومیه (مثل Applcation) لذا بصورت اختصاصی برای یک کاربر نمیتونید استفاده کنید حتی اگه میشد اینکار توصیه نمیشه .
موفق باشید

golagha_program
سه شنبه 28 مهر 1388, 23:56 عصر
با سلام.

موقعی که این تا÷یک رو نوشتم اولش ازش استقبال نشد ولی حالا می بینم که دوستان علاقمندن و تشکر می کنم از دوست خوبمalireza_s_84 که دارن این مبحث رو از اول و با جزئیات بیان می کنن.

در مورد Caching حرف زیاد.اگر بخوام تقسیم بندی کنم باید باید بگم:
1-انواع Caching
2-طریقه استفاده از Caching
3-Cache Dependency(وابستگی های نهان سازی)
4-Theard Safing

که من در اول کار یک توضیح روی همش دادم.علیرضا داره روی قسمت اول مقاله ارائه می ده.

---------------------------------------------------------------------------------------
کشینگ روی performance سایت شما تاثیر فوق العاده می ذاره تمام سایت های بزرگ دنیا دارن از این قابلیت استفاده می کنن.
----------------------------------------------------------------------------------------
در پاسخ شماSaber_Fatholahi باید بگم که فکر می کنم مشکل شما با وابستگی هاست.
در مورد Cache Dependency باید بگم که مطلب خیلی مهمیه.
شما کش رو از دیتا بیس پر می کنید این کش بصورت ایستا در حافظه سرور ذخیره می شه اگر تغییری توی دیتا بیس بدید (حذف اضافه کردن یا ویرایش داده ها) اطلاعات کش تغییر نمی کنه و از تغییرات دیتابیس شما آگاه نمیشه ولی چون توی کش اطلاعات قدیم ذخیره شده و کلید هم داره فرم های شما داده ها رو از کش می خونن که این داده ها نا معتبر است.

3 راهکار وجود داره
1-استفاده از SqlDependency که بی نهایت سخت و مزخرف و باید کلی تغییرات توی sqlserver و سیستم عامل اینها بدی فرمت Query هات باید خاص باشه توی دستوراته select دیگه نمی تونی از * استفاده کنی و کلی دردسر دیگه

2- راهکاریه که توی پست اول گفتم و حالا با کمی جزئیات می گم
گفتم برای کش باید کلید تعریف کنی مثلاً Product میشه کلید و بیانگر اینه که لیست اطلاعات جدول محصولات الان تو کشه.

می تونی هر محصولم به تنهایی بریزی تو کش با کلید Product+Serialیعنی Product1 کلید کش وجزئیات محصول 1 رو تو خودش داره.

حالا فرض کنیم تو محصول شماره 1 رو اسمش رو توی بانک تغییر می دی ولی توی کش همون اطلاعات قدیمیه و داده نا معتبر داری

اگر دقت کنی می بینی که اینها توی واژه Product یکسانن.من یک تابع نوشتم که از این واژه یکسان استفاده می کنه و این تابع رو بعد از هر Insert Update Deleteصدا می کنم و کارش اینه که همه کش هایی که با Product شروع میشن رو پاک می کنه.


public void DeletePrefix(string prefix)
{
prefix = prefix.ToLower();
List<string> itemsToRemove = new List<string>();

IDictionaryEnumerator enumerator = Cache.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().ToLower().StartsWith(pr efix))
itemsToRemove.Add(enumerator.Key.ToString());
}

foreach (string itemToRemove in itemsToRemove)
Cache.Remove(itemToRemove);
}


و بعد دوباره می شه پرشون کرد و در این صورت داده نا معتبر نداریم.در لحظه پاک کردن کش و پر کردن کش مبحث theared safing مطرح میشه که یک کلاس راهکاری براش نوشتم و توی پست اول هست و بعداً راجع بش بیشتر می گم.

حالا یک سوال آیا این روش مناسبه اگر تراکنش ما زیاد باشه و هی بخواهیم کش پر و خالی کنیم سرور خسته نمیشه؟

در حال حاضر من از این روش استفاده می کنم.

3-راهکار سوم در پاسخ به سوالیه که کردم و هنوز پیاده سازی نکردم ولی فکر می کنم بهتر از راهکار دوم باشه این روش استفاده از LINQ

من پیشنهاد می کنم بیایم لیستی از کل موجودست ها را کش کنیم مثل کل محصولات کل مشتریان.
این لیست ها رو بذاریم تو کش هر محصولی یا هر مشتری رو خواستم یک دستور لینکیو روی لیست بنویسیم و مورد رو پیدا کنیم.
هر محصول رو که حذف یا اضافه یا ویرایش کردیم با دستورات LINQ از لیست کش هم پاک کنیم یا اضافه کنیم.

حالا باید بین راهکار دوم و سوم مقایسه انجام بگیره چون هر دو بار به سرور تحمیل می کنن کدام روش بهتره ؟

اگر راهکار دیگه هم هست بگید.

---------------------------------------------------------------------------------------------
با تشکر گل آقا

persianspam
چهارشنبه 29 مهر 1388, 09:06 صبح
فرضا" ما یک دیتاست داریم که از یک سری دیتا از دیتابیس پر شده.
حالا چگونه میتوان این دیتاست را داخل یک کلید پر کرد و چطوری میتوان دوباره آن کلید را ریخت داخل دیتاست ؟

جالبه که خودم جواب خودم رو میدم :

برای ریختن یک دیتاست در کش(در اینجا کلیدی با نام Data وجود دارد که مقدار DS را داخل آن قرارمیدهیم) :


Dataset Ds = new DataSet();
ds.ReadXml(MapPath("~/Data.xml")); //برای پر کردن دیتا ست از یک دیتا که میتونه از دیتابیس پر بشه.
Cach.Insert("Data",ds);



برای بازیابی کش مورد نظر به داخل دیتاست (در اینجا دیتایی که داخل کلیدی با نام Data قرار گرفته را خوانده و در یک دیتاست قرار میدهیم):


DataSet ds = new DataSet();
ds = (Dataset)Cach.Get("Data");

با تشکر از خودم :چشمک:

marijooon
چهارشنبه 01 اردیبهشت 1389, 22:49 عصر
ببخشید که یه بحث قدیمی رو بالا آوردم ولی میشه ادامه بدید تا اینجا خیلی مفیده ولی چرا نصفه رها شده به نظر من بحث caching خیلی جالب و همینطور مهمه میشه اساتید لطف کنن و ادامه بدن؟:خجالت:

rana-writes
پنج شنبه 27 خرداد 1389, 13:49 عصر
سلام
منم ممنون میشم مبحث Cache ادامه پیدا کنه
چون توی خیلی از تاپیکها خوندم که زمانی که گرید ویو رو توی Update Panel میندازیم، بهتره که ViewState رو برای گرید False کنیم و اگه کاربر به صفحه قبلش برگرده گرید همون اطلاعات قبلی رو نشون میده، پس استفاده از Cache تو این حالت توصیه شده
خیلی خوب میشه اگه این بحث توسط اساتید ادامه پیدا کنه

ممنون

aserfg
یک شنبه 27 تیر 1389, 19:06 عصر
هر چند موضوع قدیمیه ولی شاید به درد بعضیا بخوره
از چند متد برای به روز کردن داده های یک جدول استفاده نکنید . حتی المقدور لایه caching رو از لایه های دیگر جدا کنید .

const double CacheDuration = 60.0;
private readonly string[] MasterCacheKeyArray = {"ProductsCache"};


private string GetCacheKey(string cacheKey)
{
return string.Concat(MasterCacheKeyArray[0], "-", cacheKey);
}

private object GetCacheItem(string rawKey)
{
return HttpRuntime.Cache[GetCacheKey(rawKey)];//در دسترس قرار دادن داده کش شده
}

private void AddCacheItem(string rawKey, object value)
{
System.Web.Caching.Cache DataCache = HttpRuntime.Cache;

// Make sure MasterCacheKeyArray[0] is in the cache - if not, add it
if (DataCache[MasterCacheKeyArray[0]] == null)
DataCache[MasterCacheKeyArray[0]] = DateTime.Now;

// Add a CacheDependency
System.Web.Caching.CacheDependency dependency = new System.Web.Caching.CacheDependency(null, MasterCacheKeyArray);
DataCache.Insert(GetCacheKey(rawKey), value, dependency, DateTime.Now.AddSeconds(CacheDuration), System.Web.Caching.Cache.NoSlidingExpiration);//اضافه کردن ول?و به کش که پس از 60 ثان?ه از ب?ن م? رود
}

[System.ComponentModel.DataObjectMethodAttribute(Sy stem.ComponentModel.DataObjectMethodType.Select, true)]
//----------------------
public Northwind.ProductsDataTable GetProducts()
{
const string rawKey = "Products";

// See if the item is in the cache
Northwind.ProductsDataTable products = GetCacheItem(rawKey) as Northwind.ProductsDataTable;
if (products == null)
{
// Item not found in cache - retrieve it and insert it into the cache
products = API.GetProducts();

AddCacheItem(rawKey, products);
}

return products;
}
//-----------------------------------------------------------
[System.ComponentModel.DataObjectMethodAttribute(Sy stem.ComponentModel.DataObjectMethodType.Select, false)]
public Northwind.ProductsDataTable GetProductsByCategoryID(int categoryID)// ?ک کش مختلف اضافه م? کند categoryID به ازا? هر
{
if (categoryID < 0)
return GetProducts();
else
{
string rawKey = string.Concat("ProductsByCategory-", categoryID);

// See if the item is in the cache
Northwind.ProductsDataTable products = GetCacheItem(rawKey) as Northwind.ProductsDataTable;
if (products == null)
{
// Item not found in cache - retrieve it and insert it into the cache
products = API.GetProductsByCategoryID(categoryID);
AddCacheItem(rawKey, products);
}

return products;
}
}
API در سورس بالا شیئی است برای دسترسی به متدهای لایه PRODUCTS.BLL که به صورت زیر تعریف می شود :

private ProductsBLL _productsAPI = null;
protected ProductsBLL API
{
get
{
if (_productsAPI == null)
_productsAPI = new ProductsBLL();

return _productsAPI;
}
}کدهای بالا از دموهای گروه ASP.NET است . اونایی که کمی با برنامه نویسی لایه ای و کش آشنایی دارند کدهای بالا رو متوجه خواهند شد . باید بدونیم استفاده نادرست از کش می تونه داده های متفاوتی برای کاربرامون ارسال کنه . توضیح کدها :
شیء objectdatasource در لایه presentation اطلاعات رو از متدی مانند getproducts() در خواست می کنه . در این متد ابتدا متغیر ثابتی به نام rawKey که مقدار اون برابر Products که نام جدولمونه ست می شه این بار شیئی به نامProducts که از نوع Northwind.ProductsDataTable است تعریف و مقدار اون رو برابر مقدار موجود در کش قرار می دیم با استفاده از کد :

Northwind.ProductsDataTable products = GetCacheItem(rawKey) as Northwind.ProductsDataTable;حالا چک می کنیم که آیا مقدار ی در کش وجو داشته یا نه ؟ و اگه وجو نداشت متد مناسبی از کلاس productsbll.cs فراخوانی میکنیم . با این کد:

products = API.GetProducts();

AddCacheItem(rawKey, products);API شی متناظر از کلاس PRODUCTSBLL.CS است .

نکته بسیار مهم در این کدها تعریفCacheDependency برای کش است که در متد AddCacheItem ابتدا یک نمونه از کش می سازیم به نام DataCache می سازیم و داده های در دسترس کش را به آن نسبت می دهیم . بعد یه VALUE برای KEY=MasterCacheKeyArray[0] ست می کنیم :

if (DataCache[MasterCacheKeyArray[0]] == null)
DataCache[MasterCacheKeyArray[0]] = DateTime.Now;به جای DATETIME.NOW هر مقداری می شد قرار داد .هدف ایجاد یه کش با این KEY بود . که بعدا بتونیم با استفاده از این kEY , تعلق یا وابستگی تعریف شده با کد :

System.Web.Caching.CacheDependency dependency = new System.Web.Caching.CacheDependency(null, MasterCacheKeyArray);مقادیر کش رو با استفاده از متد زیر خارج کنیم (از بین ببریم). چون زمانی تعلقی برای KEY تعریف شد به محض از بین رفتنآن تعلق مقادیر مربوط به اون KEY هم از بین میرن . و چون ما در اینجا برای تمامی KEY ها این تعلق رو گذاشتیم با محض اجرا شدن متد زیر کلیه KEY ها یا به عبارتی مقادیر کش شده متناظر با آنها از بین خواهند رفت .

public void InvalidateCache()
{
// Remove the cache dependency
HttpRuntime.Cache.Remove(MasterCacheKeyArray[0]);
}

fakhravari
شنبه 16 دی 1391, 16:42 عصر
با سلام
کدام روش حالا خوب است؟

aminmorteza
شنبه 16 دی 1391, 23:06 عصر
سلام دوستان بنده از cache به این صورت استفاده میکنم ممنون میشم نظرتون رو بگید اطلاعات رو از پایگاه می خوانم میریزم تویه یک لیست و سپس با لیست کار میکنم



if (Cache["Category"] == null)
{
var category = from c in database.Articles_Categories
select c;
cacheList = category.ToList();
Cache.Insert("Category", cacheList, null, DateTime.Now.AddMinutes(5), TimeSpan.Zero);

}
else
{
cacheList =(List<Articles_Category>)Cache["Category"] ;
}
string cat = "";
foreach(var item in cacheList)
{
if (Cache[item.Title] == null)
{
var countofcategory = (from coc in database.Articles_Articles
where coc.CategroyID == item.CategoryID && coc.IsDeleted == false && coc.IsPublished == true
select coc).Count();

Cache.Insert(item.Title, countofcategory.ToString(), null, DateTime.Now.AddMinutes(5), TimeSpan.Zero);
cat += "<div><a href=\"/Category/{0}/Page/1\">{1}({2})</a></div>";
cat = string.Format(cat, item.CategoryID, Microsoft.Security.Application.Encoder.HtmlAttribu teEncode(item.Title), countofcategory.ToString());
}
else
{
string countz = Cache[item.Title].ToString();

cat += "<div><a href=\"/Category/{0}/Page/1\">{1}({2})</a></div>";
cat = string.Format(cat, item.CategoryID, Microsoft.Security.Application.Encoder.HtmlAttribu teEncode(item.Title), countz);
}

}
Literal1.Text = cat;

Mag-Mag
یک شنبه 25 مهر 1395, 08:30 صبح
سلام
بچه ها من سوالم اینه که تا چنتا رکورد از دیتابیس رو بهینه است که بریزیم توی کش
مثلا من یک جدول دارم
حدود 6000 رکورد داره
توی سلکت هم همشو لازم دارم
چرا؟

چون مربوط به اطلاعات تقویم کاری پرسنل هست
وبرای 3000 پرسنل حداقل یک رکورد وجود داره
چه بسا برای خیلی ماه های کاری تا چند رکورد برای هر پرسنل(چون خیلی از پرسنل چندین شیفت کاری در ماه دارن ، مثل پرستارا)

و من موقع حساب کتاب ، کارکرد ماهانشون باید اطلاعات این جدول رو داشته باشم
برای مواقعی مثل مانده مرخصی کل پرسنل
باید اطلاعات کل جدول خونده بشه
تا بشه مقایسه انجام داد (به ازای کل روزهای ماه ، چه ساعت هایی نیومده و حالا اونایی که نیومده ایا مرخصی بوده ، ماموریت یا غیبت)

حالا این وسط 2 - 3 تا جدول دیگه هم هست (مثل اینکه حالا اگه مرخصی بوده ، ایا مجوز داشته یا نه)
روی هم حدود 10 هزار رکورد
میخوام بدونم این کش دات نت
به ازای هر چه مقدار رکورد ، چقدر رم رو مشغول میکنه

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

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

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

a666666
چهارشنبه 03 آذر 1395, 23:59 عصر
در این پست مجموعه تصویری آموزش ASP.Net 2010 از مبتدی تا پيشرفته را آماده کرده ایم. با مشاهده این فیلم آموزشی میتوانید یک وب سایت حرفه ای پیاده سازی کنید.
کیفیت فایل های تصویری این مجموعه کاملآ استاندارد می باشد. (http://banke-maghalat.ir/page.php?id=81)



قسمت اول (http://cld.persiangig.com/download/uTUNnQWZeb/j1_ASP.Net_Banke-maghalat.ir.rar/dl)


قسمت دوم
(http://cld.persiangig.com/download/DOFKay4V8G/j2_ASP.Net_Banke-maghalat.ir.rar/dl)

قسمت سوم
(http://cld.persiangig.com/download/gKg2eYubFE/j3_ASP.Net_Banke-maghalat.ir.rar/dl)

قسمت چهارم (http://cld.persiangig.com/download/vYTntTX4M4/j4_ASP.Net_Banke-maghalat.ir.rar/dl)

قسمت پنجم (http://cld.persiangig.com/download/46WP1LqKhA/j5_ASP.Net_Banke-maghalat.ir.rar/dl)