• Products
    مطابق با جستجوی شما محصولی یافت نشد. توجه فرمایید که در جستجو ترتیب عبارات وارد شده مهم می باشد.
    وبلاگ فیلترگذاری
    تصویر برای پست وبلاگ تفاوت Event و Delegate و مشکل نشتی حافظه (Memory Leaks) در کار با Event ها

    تفاوت Event و Delegate و مشکل نشتی حافظه (Memory Leaks) در کار با Event ها

    در این پست ابتدا به تفاوت های event و delegate می پردازیم و سپس علت مشکل نشتی حافظه رو به هنگام استفاده از اون ها بررسی میکنیم (سوالی که ممکنه بعضا توی مصاحبه باهاش برخورد کرده باشین)

    در ابتدا باید بگم که این دو خیلی شبیه به هم هستند
    1- هر دو میتونن باعث memory leak بشن
    2- هر دو این امکان رو دارن که با =+ و =- بشه چندتا متد رو بهشون اضافه یا کم کرد
    3- هر دو موقع raise شدن (اجرا شدن)، تمام متد های ثبت شده داخل خودشون رو فراخوانی میکنن

    🔹و اما تفاوت های اونها چیه؟
    در واقع event یک abstraction بر روی delegate هست که یک سری محدودیت ها (بهتره بگیم محافظت ها) رو روش اعمال میکنه
    1- اجازه نمیده event رو ریست کنین (یعنی فقط اجازه میده با += و -= متدی بهش اضافه یا کم کنین ولی اجازه نمیده که با = مقدارش رو ریست کنین)
    2- اون event رو فقط از طریق داخل کلاس شامل شوندش قابل فراخوانی میکنه یعنی از بیرون کسی نمیتونه اون event رو فراخوانی کنه

    🔸بررسی مشکل نشتی حافظه در Event و Delegate
    احتمالا خیلی جا ها دیدید یا شنیدید که میگن event ها میتونن باعث نشتی حافظه بشن. اما این مورد محدود به event نیست؛ برای delegate ها هم میتونه اتفاق بیافته. حتی برای یک شی استاتیک هم میتونه اتفاق بیافته. در واقع علت اصلی این مشکل مربوط به باقی ماندن رفرنس اشیای «بلا استفاده» هست

    فرض کنین یه کلاس static داریم که داخلش یه لیست static هست. طبیعتا طول عمر این لیست به دلیل static بودن تا پایان عمر application باقی خواهد ماند، در نتیجه GC (مخفف Garbage Collector)، اون لیست رو Dispose نمیکنه
    حالا اگر در طول برنامه اشیایی رو درون اون لیست Add کنیم عملا چون رفرنس اون اشیا داخل لیست باقی میمونن، اون اشیا هم تا پایان عمر برنامه Dispose نمیشن (حتی اگه دیگه با اون اشیا کاری نداشته باشیم) و همین عامل هست که باعث Memory Leak میشه

    حالا مشابه همین اتفاق میتونه برای event ها و delegate ها هم بیافته
    در واقع وقتی متدی از یک شی رو به یک event یا delegate (مانند Action و Func) توسط = یا =+ نسبت میدین، رفرنس اون شی هم Capture میشه، در نتیجه تا پایان عمر اون event یا delegate مربوطه، اون اشیاء هم باقی میمونن و Dispose نمیشن

    🔹برای رفع این مشکل راه حل های مختلفی هست
    1️⃣ استفاده از -= برای حذف کردن رفرنس (unsubscribe کردن) اون متد از event یا delegate مربوطه
    2️⃣ استفاده از الگوی Weak Reference Pattern که توسط کلاس WeakEventHandler دات نت پیاده سازی میشه
    3️⃣ استفاده از الگوی Event Aggregator Pattern که اون هم به نوعی از Weak Reference استفاده میکنه و داخل کتابخونه Prism زیاد ازش استفاده شده
    و روش های دیگه که خارج از توضیح این پست هست

    🔰جهت اطلاعات بیشتر و روش های جلوگیری از نشتی حافظه پیشنهاد میکنم مقالات زیر رو مطالعه کنین
    ✔️5 Techniques to avoid Memory Leaks by Events in C# .NET you should know

    ✔️Understanding and Avoiding Memory Leaks with Event Handlers and Event Aggregators

    ✔️Memory Leak in C#

    ✔️Are you afraid of event handlers because of C# memory leak?

    ✔️Events: Demystifying Common Memory Leaks

    نظر خود را ارسال کنید

    back to top
    فیلترگذاری