Should a disposed control be able to safely ignore event callbacks?
===

I have a class which is a disposable UI Control.
It subscribes to changes of a moldel object to redraw it's content.

On the other hand, under circumstances, some special change of the same model object instructs the view containing this control to remove and dispose it (the control).

As a result a change in a model, depending on subscription order - first causes the control disposal and afterwards it's method invocation - which ends up with `ObjectDisposedException`.

**Question**: Should the control be designed to safely **ignore event callbacks** or should we try to **prevent this kind of invocation** from other layers?

For those who prefer to see more code then words I have prepared a very simplified example:

    //############################################
    class View
    {
        private Control m_Control;
    
        public View(Logic logic, Model model)
        {
            m_Control = new Control(model);
            logic.Changed += LogicChanged;
        }
    
        private void LogicChanged(object sender, EventArgs e)
        {
            m_Control.Dispose();
            m_Control = null;
        }
    }
    
    //############################################
    class Control : IDisposable
    {
        private readonly Model m_Model;
    
        public Control(Model model)
        {
            m_Model = model;
            m_Model.Changed += ModelOnChanged;
        }
    
        public bool IsDisposed { get; private set; }
    
        public void Dispose()
        {
            m_Model.Changed -= ModelOnChanged;
            IsDisposed = true;
        }
    
        private void ModelOnChanged(object sender, EventArgs e)
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(ToString());
            }
            //Do something
        }
    }
    
    //############################################
    class Model
    {
        public event EventHandler<EventArgs> Changed;
    
        private void OnChanged(EventArgs e)
        {
            EventHandler<EventArgs> handler = Changed;
            if (handler != null)
                handler(this, e);
        }
    
        public void Change()
        {
            OnChanged(null);
        }
    }
    
    //############################################
    class Logic
    {
        private readonly Model m_Model;
    
        public Logic(Model model)
        {
            m_Model = model;
            m_Model.Changed += ModelOnChanged;
        }
    
        private void ModelOnChanged(object sender, EventArgs e)
        {
            OnChanged(null);
        }
    
        public event EventHandler<EventArgs> Changed;
    
        private void OnChanged(EventArgs e)
        {
            EventHandler<EventArgs> handler = Changed;
            if (handler != null)
                handler(this, e);
        }
    }
    
    //############################################
    class Program
    {
        private static void Main(string[] args)
        {
            var model = new Model();
            var logic = new Logic(model);
    
            var view = new View(logic, model);
            model.Change();
            //And crash!
        }
    }

