Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 12:14
Оценка:
Всем привет!

Такой вопрос. Есть некий класс, конструктор которого принимает в качестве параметра объект, реализующий интерфейс IDisposable.
Соответветвенно сам этот класс тоже реализует IDisposable.


class Connection : IDisposable
{
    private Socket _socket;
    
    public Connection(Socket socket)
    {
        // 1
        _socket = socket;
        // 2
    }
    
    public void Dispose()
    {
        // dispose stage 1
        _socket.Close();
        // dispose stage 2
    }
}

class Foo
{
    private void OnAccept(IAsyncResult ar)
    {
        socket = _listener.EndAccept(ar);
        new Connection(socket);
    }
}



Теперь вопрос. Что будет если случится исключение а) в точке 1; б) в точке 2.
Кто-то должен вызвать Close() сокету (иначе будет висеть у нас занятый порт до сборки мусора).

Такое:
    private void OnAccept(IAsyncResult ar)
    {
        using (socket = _listener.EndAccept(ar))
        {
            new Connection(socket);
            socket = null;
        }
    }


не прокатывает — warning CS0728: Possibly incorrect assignment to local 'conn' which is the argument to a using or lock statement. The Dispose call or unlocking will happen on the original value of the local.

Внимание, вопрос. Как это кошерно обработать?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 12:49
Оценка:
Здравствуйте, jedi, Вы писали:

J>Внимание, вопрос. Как это кошерно обработать?


В финалайзере
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 13:00
Оценка:
Здравствуйте, adontz, Вы писали:

A>В финалайзере


Спасибо, очень информативно.
А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re: Кошерное использование using
От: Lloyd Россия  
Дата: 27.06.09 13:05
Оценка: +2
Здравствуйте, jedi, Вы писали:

J>Внимание, вопрос. Как это кошерно обработать?


Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.
Re[3]: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 13:19
Оценка:
Здравствуйте, jedi, Вы писали:

J>Спасибо, очень информативно.

J>А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).

Если фрагмент кода в исходном сообщении это реальный код, а не иллюстрация, то думаю, что в точке №1 исключения не будет. С какой стати, какая там может произойти ошибка? Вы можете привести хоть один реальный пример исключения в точке №1?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: Кошерное использование using
От: anton_t Россия  
Дата: 27.06.09 13:23
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Спасибо, очень информативно.

J>>А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).

A>Если фрагмент кода в исходном сообщении это реальный код, а не иллюстрация, то думаю, что в точке №1 исключения не будет. С какой стати, какая там может произойти ошибка? Вы можете привести хоть один реальный пример исключения в точке №1?


Thread.Abort(), но это depricated вроде как.
Re[5]: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 13:35
Оценка: +1
Здравствуйте, anton_t, Вы писали:

_>Thread.Abort(), но это depricated вроде как.


Thread.Abort это какой-то экстремальный случай. В нормальной жизни бывает межпотоковая синхронизация, Thread.Interrupt на худой конец.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 13:43
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Спасибо, очень информативно.

J>>А если финалайзер вызвовется через год? Память может и не ресурс, а порты ТCP — вполне себе (странно, да?).

A>Если фрагмент кода в исходном сообщении это реальный код, а не иллюстрация, то думаю, что в точке №1 исключения не будет. С какой стати, какая там может произойти ошибка? Вы можете привести хоть один реальный пример исключения в точке №1?


Да что угодно. Поскольку это сервер к которому пишутся плагины. И ошибка в плагине не должна влиять на возможность других клиентов воспользоваться сервисом.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[2]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 13:46
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, jedi, Вы писали:


J>>Внимание, вопрос. Как это кошерно обработать?


L>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.


Я обеими руками за. Только вот не вижу как это применить в данной ситуации
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: adontz Грузия http://adontz.wordpress.com/
Дата: 27.06.09 14:28
Оценка:
Здравствуйте, jedi, Вы писали:

J>Да что угодно. Поскольку это сервер к которому пишутся плагины. И ошибка в плагине не должна влиять на возможность других клиентов воспользоваться сервисом.


Что угодно бывают разные. Сбой в оперативной памяти не та ошибочная ситуация, которую стоит обрабатывать.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 14:37
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.


Именно.
Re[3]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 14:39
Оценка:
Здравствуйте, jedi, Вы писали:

L>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.

J>Я обеими руками за. Только вот не вижу как это применить в данной ситуации

Как-как, не закрывать сокет. Пусть закрывает тот кто передает его в конструктор.
Re[4]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 14:54
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, jedi, Вы писали:


L>>>Не вдаваясь в специфику: обычно рекомендуется чтобы временем жизни объекта управлял тот, кто его создает.

J>>Я обеими руками за. Только вот не вижу как это применить в данной ситуации

MC>Как-как, не закрывать сокет. Пусть закрывает тот кто передает его в конструктор.


У него недостаточно информации, чтобы решить когда это нужно делать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[6]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:02
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Да что угодно. Поскольку это сервер к которому пишутся плагины. И ошибка в плагине не должна влиять на возможность других клиентов воспользоваться сервисом.


A>Что угодно бывают разные. Сбой в оперативной памяти не та ошибочная ситуация, которую стоит обрабатывать.


При чем здесь сбой в оперативной памяти?
Банально — пытались записать в ивент лог, что принято новое соединения, произошло исключение — не хватило прав. Все, пусть сокет висит?

Я понимаю, что сборщик мусора все это когда-то вычистит. Но для 24/7 приложения это не годится.
И, да, я знаю что можно написать так:


Socket socket = null;

try
{
    socket = _listener.EndAccept(ar);
    new Connection(socket);
}
finally
{
    if (socket != null)
        socket.Close();
}


Я всего лишь спросил, как принято поступать в таких ситуациях. Вы же принялись убеждать, что все это фигня, думать об этом не нужно и сбрщик мусора когда-то почистит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[5]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:05
Оценка:
Здравствуйте, jedi, Вы писали:

J>У него недостаточно информации, чтобы решить когда это нужно делать.


Судя по вашему примеры вы вообще заморачиваетесь. Как сказал adontz — не должно быть никакого исключения в указанных вами точках, вы придумываете из разряда "а что если завтра на нас упадет ядерная бомба" — вероятности одинаковые. Хотя у варианта с ядерной бомбой вероятность и то наверное повыше
Re[2]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:05
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, jedi, Вы писали:


J>>Внимание, вопрос. Как это кошерно обработать?


A>В финалайзере


Да, и финалайзер тут на фиг не упал. Ибо у класса Socket уже есть финалайзер, который закроет хендл сокета.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[6]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:06
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Судя по вашему примеры вы вообще заморачиваетесь. Как сказал adontz — не должно быть никакого исключения в указанных вами точках, вы придумываете из разряда "а что если завтра на нас упадет ядерная бомба" — вероятности одинаковые. Хотя у варианта с ядерной бомбой вероятность и то наверное повыше


Спасибо, Ваша помощь была для меня бесценна.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[7]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:12
Оценка:
Здравствуйте, jedi, Вы писали:

class Connection : IDisposable
{
    private Socket _socket;
    
    public Connection(Socket socket)
    {
        try
        {
          // 1
          _socket = socket;
          // 2
        }
        catch
        {
          socket.Close();
          throw;
        }
    }
    
    public void Dispose()
    {
        // dispose stage 1
        if(_socket != null)
          _socket.Close();
        // dispose stage 2
    }
}


Так чем-нибудь не устраивает?
Но повторюсь, подумайте как можно сделать дизайн так, чтобы закрытием сокета занимался тот кто его создает.
Re[8]: Кошерное использование using
От: jedi Мухосранск  
Дата: 27.06.09 15:16
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Так чем-нибудь не устраивает?


Если вы почитаете ветку выше, я привел один-в-один такой же код.
В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).

MC>Но повторюсь, подумайте как можно сделать дизайн так, чтобы закрытием сокета занимался тот кто его создает.


Вы никогда не писали асинхронных серверов? Откуда коду принимающему соединения знать когда его нужно закрыть. Логика кода нелийнейная.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[9]: Кошерное использование using
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.06.09 15:21
Оценка:
Здравствуйте, jedi, Вы писали:

J>Если вы почитаете ветку выше, я привел один-в-один такой же код.

J>В целом он меня устраивает. Я всего лишь пытался узнать есть ли какие-то штатные методы/паттерны для этой ситуации (я в .NET недавно).

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