I am new to C # and thread, and recently I started working on a utility that uses multiple threads. I have an event processing logic executed by a single thread, and then a GUI in a separate thread that monitors the event handler and receives notifications when new events are received.
When the GUI is manually closed by the user, I disconnect it so that it no longer observes the event handler. However, the next time the event handler receives the event, he thinks he still has something on this observer list. I added some printouts / breakpoints and it seems to go into NotifyObservers and fall into the foreach loop, then go to the detach method, empty the list of watchers, and then when it returns to NotifyObservers, the watcher it is trying to access has already been deleted and it gets an exception.
I saw on this page that you should use locks to prevent race conditions from occurring, and I tried to use them in the observer list before foreach in NotifyObservers and it still gets an exception. I think this may be due to a blockage of the inability to prevent the GUI from closing on another thread, so the other thread does not wait for me to try to block, but I'm new to this, so I'm not quite sure. I tried to throw a bunch of other locks in these methods, and nothing worked.
I have included the code for the 3 methods described below, Detach and NotifyObservers are in my event handler, and HandleClosing is in my browser
protected void HandleClosing(object sender, EventArgs e) { handler.Detach(this); } public void Detach(SubscriberObserver observer) { observers.Remove(observer); } public void NotifyObservers() { foreach (SubscriberObserver observer in observers) { observer.Invoke(new Action(() => { observer.Notify(); })); } }
source share