Каковы реальные издержки try / catch в C #? - PullRequest
90 голосов
/ 09 сентября 2008

Итак, я знаю, что try / catch действительно добавляет некоторые накладные расходы и, следовательно, не является хорошим способом управления потоком процесса, но откуда эти накладные расходы и каково его реальное влияние?

Ответы [ 12 ]

1 голос
/ 24 февраля 2009

Мне действительно нравится пост в блоге Hafthor , и чтобы добавить два цента к этому обсуждению, я хотел бы сказать, что мне всегда было легко, когда DATA LAYER выбрасывает только один тип исключение (DataAccessException). Таким образом, мой БИЗНЕС-СЛОЙ знает, какое исключение ожидать, и ловит его. Затем, в зависимости от дальнейших бизнес-правил (то есть, если мой бизнес-объект участвует в рабочем процессе и т. Д.), Я могу выбросить новое исключение (BusinessObjectException) или продолжить без повторного выброса.

Я бы сказал, не стесняйтесь использовать try..catch всякий раз, когда это необходимо, и используйте его с умом!

Например, этот метод участвует в рабочем процессе ...

Комментарии

public bool DeleteGallery(int id)
{
    try
    {
        using (var transaction = new DbTransactionManager())
        {
            try
            {
                transaction.BeginTransaction();

                _galleryRepository.DeleteGallery(id, transaction);
                _galleryRepository.DeletePictures(id, transaction);

                FileManager.DeleteAll(id);

                transaction.Commit();
            }
            catch (DataAccessException ex)
            {
                Logger.Log(ex);
                transaction.Rollback();                        
                throw new BusinessObjectException("Cannot delete gallery. Ensure business rules and try again.", ex);
            }
        }
    }
    catch (DbTransactionException ex)
    {
        Logger.Log(ex);
        throw new BusinessObjectException("Cannot delete gallery.", ex);
    }
    return true;
}
0 голосов
/ 04 мая 2010

Давайте проанализируем одну из самых больших возможных затрат блока try / catch при использовании там, где его не нужно использовать:

int x;
try {
    x = int.Parse("1234");
}
catch {
    return;
}
// some more code here...

А вот тот, у которого нет try / catch:

int x;
if (int.TryParse("1234", out x) == false) {
    return;
}
// some more code here

Не считая незначительного пробела, можно заметить, что эти два равносторонних фрагмента кода имеют практически одинаковую длину в байтах. Последний содержит на 4 байта меньше отступа. Это плохо?

Чтобы добавить оскорбление к травме, студент решает зациклить, в то время как ввод может быть проанализирован как int. Решение без try / catch может выглядеть примерно так:

while (int.TryParse(...))
{
    ...
}

Но как это выглядит при использовании try / catch?

try {
    for (;;)
    {
        x = int.Parse(...);
        ...
    }
}
catch
{
    ...
}

Блоки try / catch - это волшебные способы потратить впустую отступы, и мы до сих пор даже не знаем, почему это не удалось! Представьте себе, что чувствует человек, выполняющий отладку, когда код продолжает выполняться после серьезного логического недостатка, а не останавливается с приятной очевидной ошибкой исключения. Блоки try / catch - это проверка / очистка данных ленивым человеком.

Одна из меньших затрат заключается в том, что блоки try / catch действительно отключают определенные оптимизации: http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx. Полагаю, это тоже положительный момент. Его можно использовать для отключения оптимизаций, которые в противном случае могли бы нанести вред безопасным, нормальным алгоритмам передачи сообщений для многопоточных приложений, и для выявления возможных условий гонки;) Это единственный сценарий, который я могу придумать, использовать try / catch. Даже у этого есть альтернативы.

...