关于处理多线程事件异常的建议
本文关键字:异常 事件 多线程 于处理 处理 | 更新日期: 2023-09-27 18:01:48
我有一个类,触发事件委托给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
或其他东西,但这似乎是不对的。
如果能告诉我该怎么做,我将不胜感激。
UPDATE:我感谢Daniel和Henrik的回答,如果我能标记两者作为回答,我会,我决定去处理事件,因为我真的不希望它完全不被注意,我的最终解决方案如下(为其他人寻找解决方案)。
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);
}
}
}
不需要创建自己的ArrayException
。您可以使用System.AggregateException
包装多个异常。
从您的代码中,您似乎应该将循环中的调用包装到try/catch中,并在那里吞下异常。
我不明白OnSave
调用者如何从所有事件处理程序中获得单个异常而受益。由于您有多个事件句柄,并且从您的体系结构草图来看,似乎每个事件句柄都做了完全不同的事情(因为每个都必须被调用),异常空间是如此异构,以至于调用者无论如何都无法处理它。
你能试着纠正并重新运行OnSave
吗?你必须忽略成功的呼叫吗?