1

私は C# の経験はかなりありますが、この問題に遭遇したことはありません。経験豊富な C# 開発者がこの状況で何をすべきかを知っているかどうか疑問に思っていました。問題のメソッドのコードは次のとおりです: (問題はコードのブロックの後に説明されています)

public void ConnectToRemoteServer() 
{
    Console.WriteLine("Attempting to connect to " + config.GetString(ConfigParams.MasterServerIp) + ":" + config.GetString(ConfigParams.MasterServerPort));
    TcpClient client = new TcpClient();
    IPEndPoint address = new IPEndPoint(IPAddress.Parse(config.GetString(ConfigParams.MasterServerIp)), config.GetInt(ConfigParams.MasterServerPort));
    Console.WriteLine("Connecting...");
    //Begin asynchronous sever communication
    if (this.autoTask == null)
    {
        communicator = new CommunicationListener(client, config, address);
    }
    else
    {
        communicator = new CommunicationListener(client, config, address, this.autoTask);
    }
    Thread communicationThread = new Thread(new ThreadStart(communicator.Start));
    communicationThread.Start();
}

私が疑問に思っているのは、このコード ブロックで using ステートメントを使用する必要があるかどうかです。TcpClientが interface を実装していることはわかっているためIDisposable、 using ステートメントにカプセル化する必要がありますが、この場合、 を使用する新しいスレッドが開始されるため、が使用される前にブロックTcpClientの終わりに到達します。 . では、ここでステートメントを使用する必要がありますか?usingTcpClientusing

4

5 に答える 5

2

ここで using を使用しないでください。早期廃棄によりプログラムが動作しなくなります。TcpClientを新しいスレッドに正しく渡し、スレッドが最終的にそれを破棄することを確認してください。

TcpClientそこで使用できるように、子スレッドでを作成することが望ましいと思いますusing

于 2013-07-19T13:34:16.773 に答える
2

この場合、using ブロックを使用すると、using ブロックの最後に暗黙的な close() が生成されるため、使用ブロックを避けるのは正しいと思います。ブロックをいつ使用するかについての通常のアドバイスは、「オブジェクトがIDisposableを実装するときはいつでも」であるため、これはかなり一般的な悪化の原因だと思います。

これは、IDisposable の実装に関係なく、使用してはいけない場合に関する決定的な記事です。http://msdn.microsoft.com/en-us/library/aa355056.aspx

于 2013-07-19T13:42:45.590 に答える
1

一般的な経験則では、IDisposable の場合、そのオブジェクトを破棄する必要があります。

using ブロックを使用すると、簡単にそれを行うことができますが、TCPClient はこのメソッドの外で持続するため、この場合は使用できません。

本当に素敵なコードを書きたいのなら、そうするべきです。クラス内で TCPClient を宣言し、クラスに IDisposable を実装させ、新しい Dispose メソッド内で TCPClient を破棄します。(そして、スレッドを終了することについて何かをするかもしれません)。

そうすれば、クラスを using ブロック内にラップできます。

于 2013-07-19T14:03:24.977 に答える
0

違う種類の問題があると思います。CommunicationListener に IDisposable を実装し、そこでも TcpClient をインスタンス化し、CommunicationListener.Dispose 実装で TcpClient を破棄する必要があります。

CommunicationListenerを処分するのはいつですか?場合によります。

于 2013-07-19T13:35:19.813 に答える
0

このメソッドが存在するクラスと CommunicationListener の両方を使い捨てにします。次に、独自のクラスが破棄されたときに他のスレッドが実行されたままにならないように、フラグを設定して通信リスナーのスレッドをキャンセルする方法を実装します。次に、親クラスの Dispose で、CommunicationListener が停止できるようにフラグを設定し、CommunicationListener を破棄します。これにより、内部で TcpClient が破棄されます。

それが理にかなっていることを願っています。

于 2013-07-19T13:43:14.440 に答える