Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вылавливание ошибок. Различия в блоках: оператора using и try-catch-finally.  (Прочитано 14464 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« : 23-02-2017 18:28 » 

Добрый вечер.

Вопрос касательно правильного оформления обработки ошибок, а также понимания того, что происходит.

Изначально считал, что нужно:
Код: (C#)
Filestream f = null;

try {
    f = new FileStream("example.txt", FileMode.Open);

    // Здесь код работы с потоком ввода-вывода.

}

catch (Exception ex) {

    // Здесь обрабатываются исключения.

}

finally {

    if (f != null) f.Close();

}

Помимо этого встречаю запись:
Код: (C#)
using (Filestream f = new Filestream("example.txt", FileMode.Open)) {

    // Здесь код работы с потоком ввода-вывода.

}

Обе ли записи эквивалентны? Можно ли второй случай комбинировать с catch? Если в ходе блока try происходит хотя бы одно исключение, то как правильно оформить общую обработку ошибок без перечисления всех возможных исключений? И ещё: если необходимо при выходе из функции сообщить о том, что обработка не удалась, как передать это корректнее?
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 24-02-2017 14:02 » 

Соблазнился на тему плагинов к Paint.NET. Решил попробовать сделать визуализацию битовых полей из темы:
Приведу небольшой бета-пример,

Пока что получилось следующее:
Код: (C#)
using PaintDotNet;
using PaintDotNet.Base;
using PaintDotNet.Core;
using PaintDotNet.Data;
using System;
using System.IO;
using System.Drawing;

namespace AE_bfield_paintnet_plugin {

    public sealed class RAWFileTypeFactory : IFileTypeFactory {

        public FileType[] GetFileTypeInstances() {
            return new[] {new AE_bfield_FileType()};
        }
    }



    internal class AE_bfield_FileType : FileType {

        public AE_bfield_FileType() : base ("AE bfield file",
                                      FileTypeFlags.SupportsLoading,
                                      new string[] {".bin"}) {}



        protected override Document OnLoad(System.IO.Stream input) {
            checked {
                BinaryReader r = null;
                Bitmap b = null;

                try {
                    r = new BinaryReader(input);

                    UInt32 size = r.ReadUInt32();

                    int width = (int)r.ReadUInt32();
                    if (width <= 0) return null;

                    int height = (int)r.ReadUInt32();
                    if (height <= 0) return null;

                    b = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                    bool data_ready = false;
                    byte current = 0;
                    int pos = 0;

                    for (int y = 0; y < height; y++) {

                        for (int x = 0; x < width; x++) {

                            if (pos == 8) data_ready = false;

                            if (data_ready == false) {
                                current = r.ReadByte();
                                pos = 0;
                                data_ready = true;
                            }

                            if (((current >> pos) & 0x01) == 0x01) b.SetPixel(x,
                                                                              height - y -1,
                                                                              Color.White);
                            else b.SetPixel(x, height - y - 1, Color.Black);

                            pos++;
                        }
                    }
                    return Document.FromImage(b);
                }

                catch {
                    return null;
                }
            }
        }
    }
}

Теория пока изучается, поэтому до идеала далеко, но тем не менее:

* a_1.jpg (50.99 Кб - загружено 1380 раз.)
Записан
SCRIBE
Гость
« Ответ #2 : 18-01-2018 14:29 » 

Цитата
Обе ли записи эквивалентны? Можно ли второй случай комбинировать с catch? Если в ходе блока try происходит хотя бы одно исключение, то как правильно оформить общую обработку ошибок без перечисления всех возможных исключений? И ещё: если необходимо при выходе из функции сообщить о том, что обработка не удалась, как передать это корректнее?

Записи вообще не эквивалентны.
try->catch->finally универсален, using только для обьектов с реализованным интерфейсом IDisposable, просто сам вызовет Dispose, что бы не случилось.
Логично использовать using, когда это можно делать (обьект позволяет), комбинировать можно и нужно, хотя бы для того, чтобы залогировать/показать пользователю внятную ошибку.
Для меня "общая" обработка ошибок существует только в рамках логирования, все остальное, если знаешь как выйти из ситуции при ошибке, ловишь только ее и действуешь, каждый случай частный.
Всегда можно сделать что-то типа:
Код: (C#)
try{
    // code
} catch (Exception e) {
    Namespace.ExceptionHandler(e, this, "MethodName");
} finally {
    // и тут что-то пишешь, если надо
}
В итоге у тебя в обрабочике ExceptionHandler будет и сама ошибка, и обьект, что ее вызвал и название метода. Проверяй тип ошибки и обрабатывай как душе угодно имея доступ к самому обьекту, если надо в нем поменять какие-то данные или еще чего.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines