У меня есть класс, который запускает события, делегирующие DispatcherObject
цели, что нормально работает, хотя у меня есть проблема, когда если обработчик выдает исключение в своем коде события, что мне делать? Я не хочу мешать другим слушателям обрабатывать событие. Я ищу совет о том, как справиться с такой проблемой.
Учитывая абстрактный базовый класс с событием Saved
, мой шаблон будет выглядеть следующим образом:
public event EventHandler<EventArgs> Saved;
public void Save() {
try {
OnSave();
} catch (Exception) {
// What should I do here? throwing prevents subsequent handlers,
// while catching gobbles up the exception. Should this be in OnSave()?
}
}
protected virtual void OnSave() {
EventHandler<EventArgs> evt = Saved;
if (evt != null) {
var args = EventArgs.Empty;
foreach (var handler in evt.GetInvocationList()) {
var target = handler.Target as DispatcherObject;
if (target == null || target.CheckAccess()) {
var h = handler as EventHandler<EventArgs>;
if (h != null) h(this, args);
} else {
target.Dispatcher.Invoke(handler, this, args);
}
}
}
}
Я думал о создании исключения, которое содержит все исключения, такие как ArrayException
или что-то в этом роде, но это не так.
Советы о том, что делать здесь, будут очень признательны.
ОБНОВЛЕНИЕ : Я благодарю Даниэля и Хенрика за ваши ответы. Если бы я мог пометить оба ответа, как и я, я решил бы заняться обработкой события, поскольку я действительно не хочу, чтобы оно проходило Мое окончательное решение совершенно незамечено (для тех, кто ищет решение).
public event EventHandler<EventArgs> Saved;
public void Save() {
OnSave();
}
protected virtual void OnSave() {
EventHandler<EventArgs> evt = Saved;
if (evt != null) {
var args = EventArgs.Empty;
var handlers = evt.GetInvocationList();
var exceptions = new Queue<Exception>(handlers.Length);
foreach (var handler in handlers) {
try {
var target = handler.Target as DispatcherObject;
if (target == null || target.CheckAccess()) {
var h = handler as EventHandler<EventArgs>;
if (h != null) h(this, args);
} else {
target.Dispatcher.Invoke(handler, this, args);
}
} catch (Exception ex) {
exceptions.Enqueue(ex);
}
}
if (exceptions.Count == 1) {
var ex = exceptions.Peek();
throw new Exception(ex.Message, ex);
}
if (exceptions.Count > 0) {
throw new AggregateException(exceptions);
}
}
}