0

我有一个带有 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(byte PowerLevel)、QueryDeviceName()等...

像这样的代码:

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

导致 connect 方法被调用两次......为什么它在调用之间被处理?

4

1 回答 1

0

您可能想研究一下“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);
  }

其次,catch(Exception) 也是一个坏主意,您不能假设异常是超时,因为这里应该捕获许多其他异常。

至于您的答案:您可能必须在您的 requestData 方法中提供进一步的实现细节,因为那里可能有线索。例如,您要关闭连接吗?如果是这样,您最终会在下一次调用 setupConnection 时创建一个新的 TcpClient 对象,这可能就是这里发生的情况。

希望这能有所启发。

于 2008-10-15T11:28:16.283 回答