Pergunta

Eu tenho uma classe base abstrata com um campo TcpClient:

public abstract class ControllerBase
{
    internal protected TcpClient tcpClient;

Ele tem um método para configurar uma conexão:

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);
            }
        }
    }

E do que os métodos para dados de solicitação:

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

        //The rest of the code uses this.tcpClient 

Existem alguns outros, como requestRawData, etc ... eles são necessários para protocolos de comunicação hardware muito específicas, mas isso não é parte desta questão de forma alguma.

Em seguida, tenho classes que derivam dessa classe e eles substituem os métodos da classe base:

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

O código funciona sem quaisquer excepções, mas toda vez que o método setupConnection é chamado, a instância TcpClient (TCPClient) parece ser eliminados, assim que um novo é criado e o método de conexão é chamado novamente, realmente retardar o processo de comunicação.

Nota: Os métodos públicos da chamada classe criança o método RequestData, abstraindo muitos detalhes do desenvolvedor usando esta biblioteca.

Tal como SetDevicePower (byte powerlevel), QueryDeviceName () etc ...

código como este:

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

faz com que o método de conexão a ser chamado duas vezes ... por que está sendo disposta entre chamadas?

Foi útil?

Solução

Existem algumas ineficiências no método "setupConnection" que você pode querer olhar. A primeira preocupação é que você está instanciar o TcpClient quando ele está fechado. Isso não é necessário. Gostaria de dividir o check nula e lógica de conexão em 2 métodos, ou pelo menos dois blocos de código dentro do método:

  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);
  }

Em segundo lugar, o catch (Exception) também é uma má idéia, você não pode assumir a exceção é um tempo limite, uma vez que existem inúmeras outras exceções que devem ser capturados aqui.

Quanto à sua resposta: você pode ter que fornecer mais detalhes de implementação dentro do seu método RequestData, como poderia haver uma pista lá. Por exemplo, você está fechando a conexão? Se assim for, você pode acabar criando um novo objeto TcpClient na próxima chamada para setupConnection, que pode ser o que está acontecendo aqui.

Espero que isso dê uma luz.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top