Как обработать исключение в многоадресном делегате в C#?
Мне дали код, который я вызываю через многоадресный делегат.
Я хотел бы знать, как я могу догнать и обработать любое возникшее там исключение, которое пока не удалось. Я не могу изменить данный код.
Я искал вокруг и обнаружил необходимость вызова GetInvocationList(), но не совсем уверен, полезно ли это.
3 ответа
Рассмотрим код, используя GetInvocationList
:
foreach (var handler in theEvent.GetInvocationList().Cast<TheEventHandler>()) {
// handler is then of the TheEventHandler type
try {
handler(sender, ...);
} catch (Exception ex) {
// uck
}
}
Это мой старый подход, более новый подход, который я предпочитаю выше, потому что он делает вызов проще, включая использование параметров out/ref (при желании).
foreach (var singleDelegate in theEvent.GetInvocationList()) {
try {
singleDelgate.DynamicInvoke(new object[] { sender, eventArg });
} catch (Exception ex) {
// uck
}
}
который индивидуально вызывает каждого делегата, который был бы вызван с
theEvent.Invoke(sender, eventArg)
Удачного кодирования.
Не забывайте делать стандартную проверку на нуль-защиту (и, возможно, блокировку) при работе с событиями.
Вы можете пройтись по всем делегатам, зарегистрированным в многоадресном списке, и вызывать каждого из них по очереди, оборачивая каждый вызов в блок try - catch.
В противном случае вызовы последующих делегатов в многоадресной рассылке после делегата с исключением будут прерваны.
Поднятый ответ для событий, для делегатов специально попробуйте этот метод расширения:
public static class DelegateExtensions
{
public static void SafeInvoke(this Delegate del,params object[] args)
{
foreach (var handler in del.GetInvocationList())
{
try
{
handler.Method.Invoke(handler.Target, args);
}
catch (Exception ex)
{
// ignored
}
}
}
}