关于处理多线程事件异常的建议



我有一个类,触发事件委托给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吗?你必须忽略成功的呼叫吗?

最新更新