Как я уже писал в заметке о делегатах при возникновении исключения в одном из методов из списка делегата - остальные вызываться не будут. Как же обойти это?
Первое что приходит в голову - сделать некий утилитарный класс и метод для работы с делегатами:

Так как здесь мы понятия не имеем сигнатуру какого метода будут описывать делегат del, ожидаем что это будет событие и используем метод DynamicInvoke.
Тест для проверки:

Сразу было очевидно что метод DynamicInvoke будет использовать рефлексию для вызова целевого метода, что конечно отразится на производительности. Кроме рефлексии на производительность повлияет создание массива аргументов, их упаковка/распаковка при необходимости, проверка что аргументы "подходят" для целевого метода и т.д.
В качестве варианта решил передавать еще один делегат, который бы использовался для вызова целевых методов первого делегата:

Тоже самое можно сделать и для событий.
Для измерения времени выполнения использовал метод, который ничего не делает и 5 млн. его вызовов в цикле:

Результаты следующие:
- метод Invoke - 00:00:00.0357
- метод DynamicInvoke - 00:00:03.856
- с использованием Action - 00:00:00.792
Исходный код можно скачать здесь.
Комментариев нет:
Отправить комментарий