campo TcpClient de classe base abstrata constantemente a ser eliminados
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?
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.