Подтвердить что ты не робот

Должен ли объект .Net/С# вызывать Dispose() сам по себе?

Ниже приведен пример кода, написанного коллегой. Мне это кажется совершенно неправильным, но я хотел проверить. Должен ли объект вызвать свой собственный метод Dispose() из одного из своих собственных методов? Мне кажется, что только владелец/создатель объекта должен называть Dispose(), когда это делается с объектом, а не с самим объектом.

Это веб-метод .asmx, который вызывает Dispose() сам по себе. (Тот факт, что это веб-метод, вероятно, связан с вопросом в целом.) В нашей базе кода мы иногда создаем классы веб-сервисов в рамках методов других веб-сервисов, а затем вызываем на них методы. Если мой код делает это, чтобы вызвать этот метод, объект будет тост, когда метод вернется, и я больше не могу использовать этот объект.

[WebMethod]
public string MyWebMethod()
{
    try
    {
        return doSomething();
    }
    catch(Exception exception)
    {
        return string.Empty;
    }
    finally
    {
        Dispose(true);
    }
}

UPDATE: Найдено несколько ссылок, которые связаны между собой:

Нужно ли мне указывать ссылку на веб-службу в ASP.NET?

Удалить класс прокси-сервера веб-службы?

4b9b3361

Ответ 1

Конечно, это не хорошая prartice. Вызывающий должен решить, когда он закончит использовать объект IDisposable, а не сам объект.

Ответ 2

Если я когда-нибудь увижу это в одном из моих проектов, я бы спросил, почему, и я 99.9999% уверен, что все равно удалю его.

для меня это своего рода красный флаг/код пахнет

Ответ 3

Существует очень мало веских причин для выполнения действия "Самостоятельное удаление". Threading - это тот, который я использую больше, чем не.

У меня есть несколько приложений, которые "стреляют и забывают" потоки. Использование этой методологии позволяет объекту самостоятельно распоряжаться.

Это помогает поддерживать чистоту среды без процесса управления потоками.

Ответ 4

Нет никаких технических ограничений на способ использования метода Dispose. Единственное особенное в том, что Dispose вызывается в определенных конструкциях (foreach, using). Из-за этого Dispose может быть разумно использоваться для того, чтобы помечать объект как более не подлежащий использованию, особенно если вызов идемпотент.

Я бы не использовал его для этой цели, однако, из-за принятой семантики Dispose. Если бы я хотел пометить объект как более не используемый для использования внутри самого класса, тогда я бы создал метод MarkUnuseable(), который можно было бы вызывать Dispose или любым другим местом.

Ограничивая вызовы Dispose на общепринятые шаблоны, вы покупаете возможность вносить изменения в методы Dispose во всех ваших классах с уверенностью, что вы не будете неожиданно нарушать код, который отклоняется от общего шаблона.

Ответ 5

Просто удалите его, но позаботьтесь о его уничтожении во всех объектах, которые его называют.

Ответ 6

Технически да, если этот "метод" является финализатором, и вы реализуете Finalize и IDisposable pattern, как указано Microsoft.

Ответ 7

В то время как объект .Net обычно не вызывал Dispose сам по себе, бывают случаи, когда код, запущенный внутри объекта, может быть последним, что ожидает его использования. В качестве простого примера, если метод Dispose может обрабатывать очистку частично сконструированного объекта, может быть полезно, чтобы конструктор закодировал что-то вроде следующего:

Sub New()
  Dim OK As Boolean = False
  Try
    ... do Stuff
    OK = True
  Finally
    If Not OK Then Me.Dispose
  End Try
End Sub

Если конструктор будет генерировать исключение без возврата, то частично построенный объект, который намечен на отказ, будет единственной вещью, которая когда-либо будет иметь информацию и стимул для выполнения необходимой очистки. Если он не позаботится о своевременной утилизации, ничего другого не будет.

Что касается вашего конкретного фрагмента кода, шаблон несколько необычен, но он выглядит примерно так, как сокет может передаваться из одного потока в другой. Там вызов, который возвращает массив байтов и делает недействительным Socket; этот массив байтов может использоваться в другом потоке для создания нового экземпляра Socket, который берет на себя поток связи, установленный другим Socket. Обратите внимание, что данные, относящиеся к открытому сокету, - это неуправляемый ресурс, но он не может быть очень хорошо обернут в объект финализатором, потому что он часто передается тому, что сборщик мусора не видит.

Ответ 8

Нет! Это неожиданное поведение и нарушает рекомендации по лучшей практике. Никогда не делайте ничего, что неспециализировано. Ваш объект должен делать только то, что необходимо для поддержания его состояния, одновременно защищая целостность объекта для вызывающего. Вызывающий будет решать, когда это будет сделано (или GC, если ничего другого).