شرح مختصری از Event

به کد زیر توجه نمایید:

public class ConcurrentUsersService
{
    private int users;

    public event Action<int>? OnUsersChanged;

    public int Users
    {
        get => users;
        set
        {
            users = value;
            OnUsersChanged?.Invoke(value); // Triggers the event
        }
    }
}

در مثال فوق از یک event به نام OnUsersChanged استفاده شده که سبب مطلع کردن سایر Subscriberهای این کلاس از تغییرات ایجاد شده بر روی پراپرتی users می شود.

استفاده از Action<int>? به صورت Nullable باعث میشود این event زمانی که هیچ Subscriberی ندارد، Null باشد.

OnUsersChanged?.Invoke(value);

خط بالا سبب اجرای این event در کلاسهای استفاده کننده از آن می شود.

این delegate به دو شکل قابل نوشتن خواهد بود:

public event EventHandler<CustomEventArgs> MyEvent; // Traditional pattern
public event Action<int> MySimpleEvent;            // Modern shorthand

در چه مواردی می توان از این روش:

UI Frameworks (WPF, WinForms, Blazor) (Example: Button clicks, text input changes)

Cross-Component Communication Example: Notify multiple services when user count changes

Domain-Driven Design (DDD) Example: Raise domain events when an aggregate changes

Async/Await Patterns Example: Progress reporting

Game Development (Unity) Example: Trigger events when a player collects an item

نکات مهم در استفاده از Event:

  1. قبل از invoke کردن همیشه null بودن را چک منید. در اینجا استفاده از OnUsersChanged?.Invoke این مشکل را حل کرده است.
  2. از نامهای معنا دار برای event خود استفاده نمایید. OnClick
  3. در جایی که ورودی ها Complex هستند از EventHandler<T> استفاده نمایید.
  4. هر موقع کار event تمام شد، در کلاسی که subscribe کرده، از Unsubscribe برای رها کردن حافظه استفاده نمایید.
    userService.OnUsersChanged -= MyHandler; // Critical in long-lived objects
  5. از کارهای سنگین مثل فراخوانی دیتابیس در eventها خودداری نمایید.
  6. در صورتی که چند Thread به کد شما دسترسی خواهند داشت می توانید کد را Thread-Safe کنید:
private readonly object _lock = new();
public int Users
{
    get => users;
    set
    {
        lock (_lock)
        {
            users = value;
            OnUsersChanged?.Invoke(value);
        }
    }
}

کدنهایی:

    public class Sample : IDisposable
    {
        private int _users;
        public event Action<int>? OnUserChanged;
        public int Users
        {
            get { return _users; }
            set
            {
                _users = value;
                OnUserChanged?.Invoke(value);
            }
        }

        public void Dispose()
        {
            OnUserChanged = null;
        }
    }

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *