Я новичок в C # и многопоточности, и недавно я начал работать над утилитой, использующей несколько потоков.У меня есть некоторая логика обработки событий, выполняемая одним потоком, а затем графический интерфейс пользователя в отдельном потоке, который наблюдает за обработчиком событий и получает уведомления при получении новых событий.
Когда пользовательский интерфейс вручную закрывается пользователемЯ отсоединяю его, чтобы он больше не наблюдал за обработчиком событий.Однако в следующий раз, когда обработчик события получает событие, он думает, что в его списке наблюдателей все еще есть что-то.Я добавил несколько выводов / точек останова, и он, похоже, заходит в NotifyObservers и попадает в цикл foreach, затем переходит в метод detach, очищает список наблюдателей, а затем, когда он возвращается в NotifyObservers, наблюдатель, к которому он пытается получить доступ, уже удален.и он получает исключение.
На этой странице я видел, что вы должны использовать блокировки, чтобы не допустить возникновения условий гонки, и я попытался использовать один из них в списке наблюдателей перед началом foreach вNotifyObservers, и он все еще получает исключение.Я думаю, что это может быть связано с блокировкой, которая не может предотвратить закрытие графического интерфейса в другом потоке, поэтому другой поток не ждет, когда я пытаюсь заблокировать, но я новичок в этом, поэтому яне совсем уверен.Я также попытался использовать несколько других блокировок в этих методах, но ничего не дало никакого эффекта.
Я включил код для трех методов, описанных ниже, Detach и NotifyObservers находятся в моем обработчике событий,и HandleClosing у моего наблюдателя
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(); }));
}
}