Поле TcpClient абстрактного базового класса, постоянно располагаемое - PullRequest
0 голосов
/ 15 октября 2008

У меня есть абстрактный базовый класс с полем TcpClient:

public abstract class ControllerBase
{
    internal protected TcpClient tcpClient;

У него есть метод для настройки соединения:

private void setupConnection(IPAddress EthernetAddress, ushort TcpPort)
    {
        if (this.tcpClient == null || !this.tcpClient.Connected)
        {
            this.tcpClient = new TcpClient();

            try
            {
                this.tcpClient.Connect(EthernetAddress, TcpPort);
            }
            catch(Exception ex)
            {
                throw new TimeoutException("The device did not respond.\n" + ex.Message);
            }
        }
    }

А чем методы запроса данных:

 internal protected virtual byte[] requestData(IPAddress EthernetAddress, ushort TcpPort, byte[] data, bool IgnoreResponse)
    {
        setupConnection(EthernetAddress, TcpPort);

        //The rest of the code uses this.tcpClient 

Есть несколько других, таких как requestRawData и т. Д. ... они требуются для очень специфических аппаратных протоколов связи, но это никак не является частью этого вопроса.

Затем у меня есть классы, производные от этого класса, и они переопределяют методы базового класса:

public class Controller : ControllerBase
{
  internal virtual byte[] requestData(byte[] data, bool IgnoreResponse)
  {
        return base.requestData(this.eth0.EthernetAddress, this.eth0.TcpPort, data, IgnoreResponse);
  }

Код работает без каких-либо исключений, но каждый раз, когда вызывается метод setupConnection, кажется, что экземпляр TcpClient (tcpClient) удален, поэтому создается новый и снова вызывается метод connect, что действительно замедляет процесс связи.

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

Например, SetDevicePower (байт PowerLevel), QueryDeviceName () и т. Д ...

Код такой как:

Controller controller = new Controller("172.17.0.3",34000);
string name = controller.QueryDeviceName();
controller.SetDevicePower(200);

приводит к тому, что метод connect вызывается дважды ... почему он располагается между вызовами?

1 Ответ

0 голосов
/ 15 октября 2008

В методе «setupConnection» есть некоторые недостатки, которые вы можете рассмотреть. Первая проблема заключается в том, что вы создаете экземпляр TcpClient, когда он закрыт. Это не обязательно. Я бы разделил проверку на ноль и подключил логику на 2 метода или как минимум два блока кода в методе:

  if (this.tcpClient == null)
  {
    this.tcpClient = new TcpClient();
  }

  try
  {
    if (!this.tcpClient.Connected)
    {
      this.tcpClient.Connect(EthernetAddress, TcpPort);
    }
  }
  catch(Exception ex)
  {
    throw new TimeoutException("The device did not respond.\n" + ex.Message);
  }

Во-вторых, улов (исключение) также является плохой идеей. Вы не можете предполагать, что исключение является тайм-аутом, так как здесь есть множество других исключений, которые следует отловить.

Что касается вашего ответа: вам, возможно, придется предоставить дополнительные подробности реализации в вашем методе requestData, так как там может быть подсказка. Например, вы закрываете соединение? Если это так, то вы в конечном итоге создадите новый объект TcpClient при следующем вызове setupConnection, что может быть тем, что здесь происходит.

Надеюсь, это проливает свет.

...