try ... catch плодит говнокод
От: vvv848165@ya.ru  
Дата: 14.02.20 09:02
Оценка: :))) :))) :)
Что-то почти всегда минусов от исключений больше чем плюсов ...
например такой пример:
    class Program
    {

        static void Fx()
        {
            FileStream f = new FileStream("D:\\1.txt",FileMode.Append);

            f.Write(UnicodeEncoding.UTF8.GetBytes("zzz"));
            throw new Exception("test");//предположим вызвалось в процессе работы исключение!!!
            f.Close();
        }
        static void Main(string[] args)
        {
            try {
                Fx();
            }
            catch (Exception e)
            {
                Console.WriteLine("zzz");
            }
            Console.WriteLine("Hello World!");
        }
    }

во время выполнения Console.WriteLine("zzz"); Файл "D:\\1.txt" остаётся открытым и не записывается
А если подобное исключение вызывает нехорошее состояние обекта — то даже правильный GC не поможет!!!
Править такое ГГ надоедает...
Правлю я в стиле:
    finally 
            {
        if(f!=null){...}
        if(...){...}
        //задолбало полотно!!!
            }

Можно вобще не обрабатывать — закроется с ошибкой (типо почти нормально?) — но какой тогда смысл в их использовании???
Может подскажите как меньшими силами обходит похожие грабли ???
Отредактировано 14.02.2020 9:31 vvv848165@ya.ru . Предыдущая версия . Еще …
Отредактировано 14.02.2020 9:08 vvv848165@ya.ru . Предыдущая версия .
Re: try ... catch плодит говнокод
От: Maniacal Россия  
Дата: 14.02.20 09:09
Оценка: 1 (1) +1
Здравствуйте, vvv848165@ya.ru, Вы писали:

А для FileStream обязательно нужен new?

В примерах Microsoft пишут
using (FileStream fs = File.OpenRead(path))
{
    byte[] b = new byte[1024];
    UTF8Encoding temp = new UTF8Encoding(true);
    while (fs.Read(b,0,b.Length) > 0)
    {
        Console.WriteLine(temp.GetString(b));
    }
}

И даже не заморачиваются с закрыванием.

В общем, на Stack Overflow уже поднималась проблема и есть решение.
Отредактировано 14.02.2020 9:12 Maniacal . Предыдущая версия .
Re: try ... catch плодит говнокод
От: Буравчик Россия  
Дата: 14.02.20 09:13
Оценка: 1 (1) +3
Здравствуйте, vvv848165@ya.ru, Вы писали:


VYR>во время выполнения Console.WriteLine("zzz"); Файл "D:\\1.txt" остаётся открытым и не записывается

VYR>А если подобное исключение вызывает нехорошее состояние обекта — то даже правильный GC не поможет!!!

Для таких случаев предназначен блок finally. Обычно в нем освобождают ресуры.
Best regards, Буравчик
Re[2]: try ... catch плодит говнокод
От: vvv848165@ya.ru  
Дата: 14.02.20 09:13
Оценка:
Здравствуйте, Maniacal, Вы писали:

M>Здравствуйте, vvv848165@ya.ru, Вы писали:


M>А для FileStream обязательно нужен new?


M>В примерах Microsoft пишут

M>
M>using (FileStream fs = File.OpenRead(path))
M>{
M>    byte[] b = new byte[1024];
M>    UTF8Encoding temp = new UTF8Encoding(true);
M>    while (fs.Read(b,0,b.Length) > 0)
M>    {
M>        Console.WriteLine(temp.GetString(b));
M>    }
M>}
M>

M>И даже не заморачиваются с закрыванием.

FileStream fs — а если он нужен в качестве свойства в классе?
Re[2]: try ... catch плодит говнокод
От: vvv848165@ya.ru  
Дата: 14.02.20 09:14
Оценка: -1
Здравствуйте, Буравчик, Вы писали:

Б>Здравствуйте, vvv848165@ya.ru, Вы писали:



VYR>>во время выполнения Console.WriteLine("zzz"); Файл "D:\\1.txt" остаётся открытым и не записывается

VYR>>А если подобное исключение вызывает нехорошее состояние обекта — то даже правильный GC не поможет!!!

Б>Для таких случаев предназначен блок finally. Обычно в нем освобождают ресуры.

а не всёравно где бороду писать???
Re[3]: try ... catch плодит говнокод
От: Буравчик Россия  
Дата: 14.02.20 09:19
Оценка:
Здравствуйте, vvv848165@ya.ru, Вы писали:

Б>>Для таких случаев предназначен блок finally. Обычно в нем освобождают ресуры.

VYR> а не всёравно где бороду писать???

Нет, не все равно. finally гарантирует освобождение ресурса, даже при наличии исключений.
В других местах — гарантий нет.
Best regards, Буравчик
Re[3]: try ... catch плодит говнокод
От: Mystic Artifact  
Дата: 14.02.20 09:23
Оценка: +1
Здравствуйте, vvv848165@ya.ru, Вы писали:

Б>>Для таких случаев предназначен блок finally. Обычно в нем освобождают ресуры.

VYR> а не всёравно где бороду писать???
Не всё равно. Конструкция try/catch/finally, или даже try/finally. Делать же catch ради высвобождения ресурсов — вредно.
Проблема, в том, что одни люди не понимают как работать с исключениями, а вторые — не совсем еще осознали, что GC лишь помогает, а детерминированное управление ресурсами там же где и раньше — на ваших плечах.
Re[4]: try ... catch плодит говнокод
От: vvv848165@ya.ru  
Дата: 14.02.20 09:27
Оценка: :)
Здравствуйте, Mystic Artifact, Вы писали:

MA>Здравствуйте, vvv848165@ya.ru, Вы писали:


Б>>>Для таких случаев предназначен блок finally. Обычно в нем освобождают ресуры.

VYR>> а не всёравно где бороду писать???
MA> Не всё равно. Конструкция try/catch/finally, или даже try/finally. Делать же catch ради высвобождения ресурсов — вредно.
MA> Проблема, в том, что одни люди не понимают как работать с исключениями, а вторые — не совсем еще осознали, что GC лишь помогает, а детерминированное управление ресурсами там же где и раньше — на ваших плечах.
Да блин зацепились...
Еслиб исключений небыло а только возвращались бы коды ошибок — то было бы подругому...
и борода былабы меньше и писалась она бы в нужных местах...
Отредактировано 14.02.2020 9:28 vvv848165@ya.ru . Предыдущая версия .
Re[3]: try ... catch плодит говнокод
От: Слава  
Дата: 14.02.20 09:40
Оценка: :))
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>FileStream fs — а если он нужен в качестве свойства в классе?


Значит реализуйте в классе IDisposable.

PS: Какой-то КЫВТ стал добрый, никто ещё не отправил топикстартера читать Троелсена, букварь или просто в Бобруйск.
Re[5]: try ... catch плодит говнокод
От: Mystic Artifact  
Дата: 14.02.20 09:42
Оценка: 6 (2)
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>Да блин зацепились...

VYR>Еслиб исключений небыло а только возвращались бы коды ошибок — то было бы подругому...
VYR>и борода былабы меньше и писалась она бы в нужных местах...
Если бы в хроме гугл использовал исключения — он валился бы гораздо чаще и было бы исправлено больше багов. Но свидетели секты гугла и C++ такого принять не могут, и поэтому просто пишут "if (!something_) return;", что означает приблизительно следующее: если что-то пошло не так, то ну его нафиг. Пока такого стиля код находится в очистке ресурсов — все ок, но он на практике везде, а львиная доля методов не возвращает никаких ошибок, потому что иначе можно здохнуть под весом их кодов.

Вся прелесть исключений в том, что если их не использовать — то они всё равно работают.

Вся прелесть исключений в том, что обрабатывать надо только восстановимые ошибки.

Я не говорю, что они идеальны, у них есть некоторые проблемы даже в современных языках, и то это наверное не про C#. Но они явно лучше чем голые коды ошибок.

И это не повод их пихать везде где только нельзя.

Изначально, я пытался указать,что проблема не в исключениях, а что написанный код (пример), был написан неправильно и файл не закрывался в случае возникновения исключения. Решается это с помощью using.

Соответственно обе обозначенные проблемы дизайна в изначальном топике (высвобождение ресурсов и исключения) — по большому счету не релевантны.
Re[5]: try ... catch плодит говнокод
От: Poopy Joe Бельгия  
Дата: 14.02.20 09:44
Оценка: :)
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>Здравствуйте, Mystic Artifact, Вы писали:


MA>>Здравствуйте, vvv848165@ya.ru, Вы писали:


Б>>>>Для таких случаев предназначен блок finally. Обычно в нем освобождают ресуры.

VYR>>> а не всёравно где бороду писать???
MA>> Не всё равно. Конструкция try/catch/finally, или даже try/finally. Делать же catch ради высвобождения ресурсов — вредно.
MA>> Проблема, в том, что одни люди не понимают как работать с исключениями, а вторые — не совсем еще осознали, что GC лишь помогает, а детерминированное управление ресурсами там же где и раньше — на ваших плечах.
VYR>Да блин зацепились...
VYR>Еслиб исключений небыло а только возвращались бы коды ошибок — то было бы подругому...
VYR>и борода былабы меньше и писалась она бы в нужных местах...

Ну так и напиши обертку над System.IO которая перехватывает исключения и возвращает ошибку или результат. Вот делов-то...
Re[6]: try ... catch плодит говнокод
От: Mystic Artifact  
Дата: 14.02.20 09:47
Оценка:
Здравствуйте, Poopy Joe, Вы писали:

PJ>Ну так и напиши обертку над System.IO которая перехватывает исключения и возвращает ошибку или результат. Вот делов-то...

Тогда уж сразу вокруг нативных API.
Re[6]: try ... catch плодит говнокод
От: vvv848165@ya.ru  
Дата: 14.02.20 09:48
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

MA> Вся прелесть исключений в том, что обрабатывать надо только восстановимые ошибки.

Раскажи по подробне!
Re[3]: try ... catch плодит говнокод
От: Evgeny.Panasyuk Россия  
Дата: 14.02.20 10:01
Оценка:
Здравствуйте, vvv848165@ya.ru, Вы писали:

M>>
M>>using (FileStream fs = File.OpenRead(path))
M>>

VYR>FileStream fs — а если он нужен в качестве свойства в классе?

Тогда приплыли, ибо тогда класс становится IDisopsable и его тоже надо оборачивать в using, но главное что это касается также всех кто напрямую или косвенно содержат объект этого класса. Но, это проблема только в языках без нормального scope-based lifetime (using'и, try-with-resources, with, как видишь, проблему не решают)
Re[5]: try ... catch плодит говнокод
От: TG  
Дата: 14.02.20 10:03
Оценка:
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>Да блин зацепились...

VYR>Еслиб исключений небыло а только возвращались бы коды ошибок — то было бы подругому...
VYR>и борода былабы меньше и писалась она бы в нужных местах...

Про коды ошибок и исключения см. тут: https://rsdn.org/forum/philosophy/1500888.1
Автор: Sinclair
Дата: 22.11.05
и https://rsdn.org/forum/philosophy/1512953.1
Автор: IT
Дата: 30.11.05
.
Отредактировано 14.02.2020 10:05 TG . Предыдущая версия .
Re[7]: try ... catch плодит говнокод
От: Maniacal Россия  
Дата: 14.02.20 10:04
Оценка: 1 (1)
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>Здравствуйте, Mystic Artifact, Вы писали:


MA>> Вся прелесть исключений в том, что обрабатывать надо только восстановимые ошибки.

VYR>Раскажи по подробне!

Если пользователь пытается, например, открыть файл, функция кидает исключение, пользователь видит сообщение об ошибке и исправляется. А вот Access Violation ловить не нужно.
Re[6]: try ... catch плодит говнокод
От: vvv848165@ya.ru  
Дата: 14.02.20 10:12
Оценка:
Здравствуйте, TG, Вы писали:

TG>Здравствуйте, vvv848165@ya.ru, Вы писали:


VYR>>Да блин зацепились...

VYR>>Еслиб исключений небыло а только возвращались бы коды ошибок — то было бы подругому...
VYR>>и борода былабы меньше и писалась она бы в нужных местах...

TG>Про коды ошибок и исключения см. тут: https://rsdn.org/forum/philosophy/1500888.1
Автор: Sinclair
Дата: 22.11.05
и https://rsdn.org/forum/philosophy/1512953.1
Автор: IT
Дата: 30.11.05
.

либо занимайся ООП при оработке ошибок (даже вложеную цепочку можно построить)
либо гадай на каком этапе была ошибка, что в try...catch невозможно узнать без костылей...
Re[7]: try ... catch плодит говнокод
От: Mystic Artifact  
Дата: 14.02.20 10:13
Оценка:
Здравствуйте, vvv848165@ya.ru, Вы писали:

MA>> Вся прелесть исключений в том, что обрабатывать надо только восстановимые ошибки.

VYR>Раскажи по подробне!
Погугли пожалуйста, тема обсосана 100500 раз. Хотя... в разные года были разные мнения.

Если коротко и на пальцах: обрабатывать в своём коде следует только то, что твой код может (осмысленно) обработать.

(1) Например, ты пытаешься открыть файл журнала и добавить в него запись и закрыть. Но открыть файл не получилось. Данная ситуация легко ловится кэтчем по заданному типу исключению (и желательно с фильтром по коду ошибки.) Как акт по "восстановлению" — ты можешь попробовать выполнить данную операцию снова, либо записать в другой файл журнала. Это будет более-менее осмысленная обработка, и в данном случае она выполняется уровнем выше, чем реализация.

(2) Например, всё так же как выше, но получаешь ты NullReferenceException — ты его ждал? Нет. Можешь сейчас предпринять что-то полезное, кроме как телепортировать джина с дебаггером,что б пофиксил баг? Нет. Значит наш обработчик не должен это обрабатывать.

Вероятности:

(3) Например, пользователь сохраняет документ. Тут мы можем ожидать огромный спектр неизвестных ошибок. От внутренних багов до иных сбоев. Крупные проекты как правило включают связки сторонних библиотек и компонент, и реально предсказать работу сложно. Скорее всего, в такой ситуации не стоит падать при первой возможности, так у пользователя появится шанс не потерять свои последние пол часа жизни зря. Впрочем, это правило более-менее относится ко всему UI. В тоже время это относится только к тем, приложениям, которые на это рассчитаны, иначе только падать.

Инфраструктура:

(4) Все обработчики верхнего уровня служат целям подобным (3), но либо пишут в лог, либо в соотв. со своими требованиями. Они нужны и должны кэтчить всё. Когда говорят что кэтчить всё нельзя — имеют ввиду (1)/(2), но не (4).
Re: try ... catch плодит говнокод
От: sergii.p  
Дата: 14.02.20 10:19
Оценка:
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>Что-то почти всегда минусов от исключений больше чем плюсов ...


если использовать С++, то плюсов больше
А в С# можно пробовать "RAII на костылях" http://sergeyteplyakov.blogspot.com/2014/03/raii-c-vs-idisposable.html
Re[8]: try ... catch плодит говнокод
От: Mystic Artifact  
Дата: 14.02.20 10:23
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

Ну, очень много логики довольно легко строится на принципе была ошибка или нет. Как типичная реакция на нее, к примеру, запись в журнал и постановка этой задачи обратно в очередь на выполнение. Если кто-то в таком коде придерется к тосу что он ловит всё — дайте ему в рожу.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.