Нужно ли закрывать клиент ссылки на службу .NET, когда я это сделаю?
Я пытаюсь выяснить, необходимо ли закрыть клиент ссылочного сервиса .net, когда вы закончите его использование. Почти все примеры, с которыми я столкнулся в сети, похоже, но клиент, который сгенерирован, реализует IDisposable, и поскольку он открывает соединение с сервисом, моя интуиция подсказывает, что вам нужно закрыть это соединение, когда вы выполняются с ним.
Вот пример кода, который я вытащил из http://msdn.microsoft.com/en-us/library/bb386386(v=VS.90).aspx:
private void button1_Click(System.Object sender, System.EventArgs e)
{
ServiceReference1.Service1Client client = new
ServiceReference1.Service1Client();
string returnString;
returnString = client.GetData(textBox1.Text);
label1.Text = returnString;
}
Я бы подумал, что вы должны хотя бы вызвать client.Close() в конце этого метода и лучше всего обернуть первую строку в инструкции using. Я просто хотел получить некоторые отзывы об этом, чтобы узнать, какие лучшие методы.
Ответы
Ответ 1
Да, это так, но при этом нужно быть очень осторожным. Закрывая все, что реализует ICommunicationObject
, существует потенциал, чтобы вызвать удаление объекта за чрезмерное количество времени в том случае, если там является ошибкой или неисправностью на канале.
Из-за этого предписывается, что вы вызываете метод Close
, а затем вызываете метод Dispose
на IDisposable
, используя ряд уловов для определенных типов исключений и вызывая Abort
, прежде чем вы окончательно вызовете Dispose
.
Вы можете обернуть эту логику в реализацию IDisposable
, которую вы можете использовать в инструкции using
, так как я описанный в блоге пост по этому вопросу.
Ключевым моментом здесь является создание маркера, который реализует IDisposable
, а затем в этой реализации, вызовите Close
, поймайте соответствующие исключения, вызовите Abort
(если необходимо), а затем вызовите Dispose
.
Это реализовано как метод расширения, который возвращает на нем IDisposable
, который, в свою очередь, позволяет использовать его в инструкции using
.
Ответ 2
Лучшей практикой является то, что если класс реализует IDisposable, вызовите Dispose()
в предложении finally
или оберните его using () { }
Edit
Следуя нижеприведенному комментарию @casperOne, кажется, что с WCF-клиентами следует обращаться более осторожно. Я этого не знал, и я немного расстроен этим, используя(), который хорошо служил мне до сих пор.
Ответ 3
Лучше всего посмотреть на сгенерированный клиентский код для Dispose()
и посмотреть, действительно ли он избавляется от чего-либо, например HTTP-соединений или чего-то еще.
С одной стороны, может быть, только интерфейс, который он реализует, наследует от IDisposable
, потому что некоторым клиенту может потребоваться избавиться от чего-то, даже если этого нет. Это похоже на MemoryStream, класс, который реализует IDisposable
, потому что все Stream
делают, но на самом деле это не касается неуправляемые ресурсы.
С другой стороны, никогда не помешает использовать using
, даже если Dispose()
- пустой метод. И примеры MS на самом деле действительно плохо не использовать using
, даже если они должны (например, здесь), поэтому не принимайте их пример как хорошие доказательства того, что вам не нужно.