Правильное подключение к серверу TcpClient.ConnectAsync

195
27 декабря 2017, 17:50

После выполнения метода Client.main выбрасывается исключение ObjectDisposedException (Доступ к ликвидированному объекту невозможен). Метод main предназначен для установления соединения с сервером, планируется использовать подключенный к серверу объект client в методах для отправки и получения данных на стороне клиента. Если я оберну код в блоке try в using, то ошибка исчезнет, но мне нужна возможность использовать данный TcpClient в других методах класса клиента.

Не понятна суть этой ошибки, почему объект TcpClient при выходе из метода main уничтожается, хотя он объявлен как член класса. Также непонятно, почему это исключение пропадает при закрытии сетевого потока и удалении экземпляра TcpClient в конце метода. Буду благодарен, если кто-то ответит на эти вопросы. В конце кода привел метод принятия запроса подключения на стороне сервера (метод Server.Listen).

    internal static async void main()
    {
        try
        {
            client = new TcpClient(AddressFamily.InterNetwork);
            IPAddress ipAddress = IPAddress.Parse(Form1.frm1.textBox3.Text);
            await client.ConnectAsync(ipAddress, port);
            if (client.Connected)
                Form1.frm1.textBox2.AppendText("Подключение к серверу выполнено" + Environment.NewLine);
            stream = client.GetStream();
        }
        catch (Exception ex)
        {
            Form1.frm1.textBox2.AppendText(ex.Message + Environment.NewLine);
            Disconnect();
        }
    }
   static internal async void Listen()
       server = new TcpListener(localAddr, port);
       server.Start();
       while (true)
            {
                try
                {
                    if (server.Pending())
                    { 
                        TcpClient client = await server.AcceptTcpClientAsync();
                        ClientObjects clientObject = new ClientObjects(client);
                        clientObject.Process();                          
                    }
                }
                catch (Exception e)
                {
                    Form1.frm1.textBox2.BeginInvoke(new Action(() => { Form1.frm1.textBox2.AppendText(e.Message + Environment.NewLine); }));
                    break;
                }
             }
    static internal void Disconnect()
    {
        if (stream != null)
            stream.Close(); //отключение потока
        if (client != null)
            client.Close(); //отключение клиента
    }

UPD: Вынес инициализацию объекта TcpClient из блока try-catch. Ошибка сохранилась. Добавил сюда код метода Disconnect

Answer 1

вынести инициализацию client = new TcpClient(AddressFamily.InterNetwork); из блока try{} выше, просто первой строкой main()

описание try-catch

Из блока try следует инициализировать только те переменные, которые в нем объявлены. ... Попытка использовать эту переменную вне блока try... приведет к ошибке компиляции.

как бы try-catch должен "прибрать за собой" :) видимо client после выхода из блока try{} выполняет Dispose(), т.к. класс TcpClient наследует интерфейс IDisposable... но этот экземпляр является полем другого ещё существующего объекта, его ресурсы освобождать рано (если это и делать, то только "сверху вниз").

READ ALSO
Управление Exchange Mail Server с помощью C#

Управление Exchange Mail Server с помощью C#

Добрый деньИмеется почтовый сервер Exchange 2013

129
Сумма чисел с плавающей точкой

Сумма чисел с плавающей точкой

Пытаясь посчитать сумму чисел заметил следующее поведение: 07 + 0

161
Обновление формы вариативного товара

Обновление формы вариативного товара

Всем приветСразу хочу сообщить-оправдаться, что только начинаю разбираться в веб-разработке

198
Необычное поведение javascript

Необычное поведение javascript

Добрый день! У меня есть массив который загружается с базы данныхЕсли после загрузки массива отобразить его в консоль, то он без проблем отобразится

165