Нужно ли закрывать клиент ссылки на службу .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, даже если они должны (например, здесь), поэтому не принимайте их пример как хорошие доказательства того, что вам не нужно.