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 メソッドが 2 回呼び出される原因となります...呼び出しの間に破棄されるのはなぜですか?

4

1 に答える 1

0

「setupConnection」メソッドには非効率な点がいくつかあるので、調べてみてください。最初の懸念は、閉じたときに TcpClient をインスタンス化していることです。これは必要ありません。null チェックを分割し、ロジックを 2 つのメソッドに分割するか、メソッド内に少なくとも 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 に答える