Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как правильно реализовать интерфейс IDisposable / 17 сообщений из 17, страница 1 из 1
06.04.2017, 14:25
    #39434181
Как правильно реализовать интерфейс IDisposable
Всем привет. Вопрос начинающего. Верно ли реализован метод Dispose в этом классе ?

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  public class Data_Reader_Service : IDisposable
  {
    private OracleConnection   drs_connection = Connection_Service.Factory.Build();
    public  OracleDataReader   drs_reader;
    public  Data_Reader_Service(string SQL) // конструктор
    {
      OracleCommand command = new OracleCommand();
      command.CommandText = SQL;
      command.Connection = drs_connection;
      drs_connection.Open();
      drs_reader = command.ExecuteReader();
    }

    public void Dispose()
    {
      if (!(drs_connection.State == ConnectionState.Closed)) drs_connection.Close();
    }

  }



Пример использования

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
  public static class My_Table_Data_Operation
  {

    public static void Fill(DataTable table)
    {
      using ( Data_Reader_Service drs = new Data_Reader_Service("select * from My_Table") )
      {
        if (drs.drs_reader.HasRows)
        {
          table.Rows.Clear();
          while (drs.drs_reader.Read()) table.Rows.Add
              (
              drs.drs_reader["MyColumnName1"],
              drs.drs_reader["MyColumnName2"],
              drs.drs_reader["MyColumnName3"],
              drs.drs_reader["MyColumnName4"]
              );
        } 
      } 
    }
  }
...
Рейтинг: 0 / 0
06.04.2017, 14:34
    #39434183
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Новичок ООП..Всем привет. Вопрос начинающего. Верно ли реализован метод Dispose в этом классе ?
https://msdn.microsoft.com/ru-ru/library/b1yfkh5e(v=vs.110).aspx
...
Рейтинг: 0 / 0
06.04.2017, 14:36
    #39434187
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Новичок ООП..,
drs_connection может быть null!
...
Рейтинг: 0 / 0
06.04.2017, 14:42
    #39434195
Как правильно реализовать интерфейс IDisposable
ЕвгенийВ,
нужно как-то так сделать ?
Код: c#
1.
2.
3.
      if (!(drs_connection==null))
        if (!(drs_connection.State == ConnectionState.Closed))
          drs_connection.Close();
...
Рейтинг: 0 / 0
06.04.2017, 14:43
    #39434196
Как правильно реализовать интерфейс IDisposable
Roman Mejtes, ссылку читал - там очень корявым языком написано, ничего не понятно.
...
Рейтинг: 0 / 0
06.04.2017, 15:04
    #39434226
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
вообще держать открытым подключение не имеет смысла, лучше открывать его и закрывать по необходимости через и высвобождать через using.
я кинул вам на бест практикс шаблон

создаете закрытый метод Dispose(true), и вызываете его с параметром true из метода который имплиментирует интерфейс, а после вызова помечаете его в сборщике как высвобожденный методом GC.SuppressFinalize(this); после чего сборщик не будет запускать Dispose для данного объекта, + добавить в финализатор вызов Dispose(false).
При вызове Dispose(false) нужно исключить все возможные исключения при выполнении, а так сделать выполнение максимально быстрым, без задержок.
Почему так? Причина кроется в том, что финализатор вызывается сборщиком мусора, во время очистки памяти, на очистку памяти выделяется определенный период времени, если он будет превышен очистка прервётся, при этом вся программа просто зависнет и не будет отвечать на запросы пользователя, а если упадет с исключением (Exception) то ваша программа просто упадет.
Примеры как надо, в ссылке выше.
Предположим, что в момент вызова сборщиком мусора финализатора у вас пропадет сеть, а в диспосе идет какой то сетевой запрос или обращение к какому то сетевому ресурсы, всё может зависнуть секунд на несколько секунд.
...
Рейтинг: 0 / 0
06.04.2017, 15:07
    #39434229
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
нинзя фикс, после SuppressFinalize сборщик не будет запускать финализатор объекта, а не Dispose, а вот уже из финализатора вы дерните Dispose(false).
По сути, в методе bool disposing говорит о том, что финализатор запущен вызван вам из кода, а false, его вызвал сборщик мусора через деструктор
...
Рейтинг: 0 / 0
06.04.2017, 15:27
    #39434254
Как правильно реализовать интерфейс IDisposable
Roman Mejtesдержать открытым подключение не имеет смысла, лучше открывать его и закрывать по необходимости через и высвобождать через usingа это замечание к чему? весь смысл моего кода как раз и заключается в том, чтобы немедленно закрыть connection после того, как отработает DataReader и я как раз использую using для этого -
собсно с этого самого using всё и началось - так я узнал, что нужно реализовать интерфейс IDisposable
и так я до сих пор не понял, зачем я должен реализовывать перегруженный метод
Код: c#
1.
protected void Dispose(bool disposing)
...
Рейтинг: 0 / 0
06.04.2017, 15:50
    #39434280
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Новичок ООП..,

я же уже написал вам, чтоб выгружать неуправляемые ресурсы безопасно. Чтоб исключить зависания, падения во время работы сборщика мусора.
В финализаторе добавляют Dispose(false), что высвободить те ресуры, которые (возможно) забыл высвободить программист, но если он не забыл, то финализатор (деконструтор) вообще не будет вызываться, так как вы уже вызвали SupressFinalize.
Всё эту схему с ~, Dispose, Dispose(true) делают именно для таких случаев. А как реазовывать это ваша личное дело. Вы спросили как лучше, я вам написал, что признанным шаблоном в C# является такой способ. вы либо делайте по шаблону как все, либо делайте свой код и не кто не говорит, что он может получиться хуже.
Просто представьте садитсья другой программист работать с вашим кодом, если вы всё делайте по шаблону который ему должен быть знаком, ему будет значительно прще разобраться и найти проблему в вашем коде, а так же от куда оно проистекает. Из сборщика мусора или где то в коде. Тем более, что ошибка из сборщика мусора может возникнуть в совершенно неожиданный момент и локализовать её может быть очень сложно, если у вас программа не работает в режиме отладки.
...
Рейтинг: 0 / 0
06.04.2017, 15:56
    #39434295
Как правильно реализовать интерфейс IDisposable
Roman Mejtesя же уже написал вам, чтоб выгружать неуправляемые ресурсы безопасно.вы же видите, что мой класс не содержит никаких неуправляемых ресурсов. Тогда к чему это замечание, всё никак не пойму.
...
Рейтинг: 0 / 0
06.04.2017, 17:12
    #39434361
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Новичок ООП..весь смысл моего кода как раз и заключается в том, чтобы немедленно закрыть connection после того, как отработает DataReader

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
using(SqlConnection connection = new SqlConnection("connection string"))
{

    connection.Open();

    using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
    {
        using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            if (reader != null)
            {
                while (reader.Read())
                {
                    //do something
                }
            }
        } // reader closed and disposed up here

    } // command disposed here

} //connection closed and disposed here
...
Рейтинг: 0 / 0
06.04.2017, 18:34
    #39434420
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Новичок ООП..Тогда к чему это замечание, всё никак не пойму.

к чему к чему, видимо на пути к знаниям, полезно знать зачем так делается.

а по сути, для возможности расширения твоего класса, в который могут добавиться неуправялемые ресурсы.
...
Рейтинг: 0 / 0
07.04.2017, 09:29
    #39434554
Как правильно реализовать интерфейс IDisposable
спасибо всем участникам дискуссии,
пишите ещё.
...
Рейтинг: 0 / 0
07.04.2017, 09:31
    #39434555
Как правильно реализовать интерфейс IDisposable
hVosttдля возможности расширения твоего класса, в который могут добавиться неуправляемые ресурсыне могли бы вы привести пример, когда возникает необходимость добавления неуправляемых ресурсов (и пример самих таких ресурсов)
...
Рейтинг: 0 / 0
07.04.2017, 09:48
    #39434570
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Новичок ООП..не могли бы вы привести пример, когда возникает необходимость добавления неуправляемых ресурсов (и пример самих таких ресурсов)

Например, требуется заменить провайдер на какой-нибудь экзотический, подключаемый через [DllImport], и освобождать ресурсы вручную.
...
Рейтинг: 0 / 0
07.04.2017, 10:51
    #39434609
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Arm79,
Достаточно только
Код: c#
1.
2.
using(SqlConnection connection = new SqlConnection("connection string"))
{
...
Рейтинг: 0 / 0
07.04.2017, 10:54
    #39434615
ЕвгенийВ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как правильно реализовать интерфейс IDisposable
Новичок ООП..ЕвгенийВ,
нужно как-то так сделать ?
Код: c#
1.
2.
3.
      if (!(drs_connection==null))
        if (!(drs_connection.State == ConnectionState.Closed))
          drs_connection.Close();



Достаточно
Код: c#
1.
drs_connection?.Close();
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как правильно реализовать интерфейс IDisposable / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]