Domanda

Ho una classe base astratta con un campo TcpClient:

public abstract class ControllerBase
{
    internal protected TcpClient tcpClient;

Ha un metodo per impostare una connessione:

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 rispetto ai metodi per richiedere i dati:

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

        //The rest of the code uses this.tcpClient 

Ce ne sono alcuni altri, come requestRawData, ecc ... sono necessari per protocolli di comunicazione hardware molto specifici, ma questo non fa parte di questa domanda in alcun modo.

Ho quindi classi che derivano da questa classe e hanno la precedenza sui metodi della 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);
  }

Il codice funziona senza eccezioni, ma ogni volta che viene chiamato il metodo setupConnection, l'istanza TcpClient (tcpClient) sembra essere eliminata, quindi ne viene creata una nuova e viene richiamato il metodo connect, rallentando davvero il processo di comunicazione.

Nota: i metodi pubblici della classe figlio chiamano il metodo requestData, astrarre molti dettagli dallo sviluppatore usando questa libreria.

Come SetDevicePower (byte PowerLevel), QueryDeviceName () ecc ...

Codice come questo:

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

fa sì che il metodo connect venga chiamato due volte ... perché viene disposto tra le chiamate?

È stato utile?

Soluzione

Ci sono alcune inefficienze in " setupConnection " metodo che potresti voler esaminare. La prima preoccupazione è che stai istanziando TcpClient quando è chiuso. Questo non è necessario Dividerei il controllo null e collegherei la logica in 2 metodi, o almeno due blocchi di codice all'interno del metodo:

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

In secondo luogo, anche la cattura (eccezione) è una cattiva idea, non si può presumere che l'eccezione sia un timeout, in quanto vi sono numerose altre eccezioni che dovrebbero essere rilevate qui.

Per quanto riguarda la tua risposta: potrebbe essere necessario fornire ulteriori dettagli di implementazione all'interno del metodo requestData, poiché potrebbe esserci un indizio. Ad esempio, stai chiudendo la connessione? In tal caso, finiresti per creare un nuovo oggetto TcpClient alla prossima chiamata a setupConnection, che potrebbe essere ciò che sta accadendo qui.

Spero che questo faccia luce.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top