3

ソケットを介してサーバーにメッセージを送信するモジュールを実装しようとしています。マルチスレッド環境で使用されるため、この「クライアント」オブジェクトはスレッド間で共有されます。私の質問は、このクラスをスレッドセーフにするために、Sendメソッドのロックブロックを使用する必要があるということです。(おそらくそうですが、ロックがないサンプルコードをたくさん見ました。)

これが私のMessengerClientクラスの簡略版です。

public class MessengerClient
{
    private Socket socket;
    public MessengerClient()
    {
        socket = new Socket(SocketType.Stream, ProtocolType.IPv4);
    }

    public void Connect(string host, int port)
    {
        socket.Connect(host, port);
    }

    public void SendMessage(IMessage message)
    {
        var buffer = ObjectConverter.ConvertToByteArray(message);

        var args = new SocketAsyncEventArgs();
        args.Completed += args_Completed;
        args.SetBuffer(buffer, 0, buffer.Length);

        //lock (socket)
        //{
            socket.SendAsync(args);
        //}
    }
}
4

1 に答える 1

1

Socketのドキュメントによると:

スレッドセーフ:

このクラスのインスタンスはスレッドセーフです。

したがって、スレッドセーフはややあいまいな用語ですが、このコンテキストで意味するのは、インスタンスメソッドを含むこのクラスのメソッドは、ユーザーの観点からはアトミックに見えるということです。メソッドを呼び出すと、他のスレッドでほぼ同時に呼び出されたメソッドの前または後に完全に実行されたかのように見えることがわかります。あるメソッドの半分を実行し、次に別のメソッドを実行してから、最初のメソッドを終了することはありません(分割したときに出力が完全にアトミックになることを保証できる場合を除く)。

つまり、を追加する必要はありませんlock。このSocketクラスは、複数のスレッドから同時に[またはその周辺で]メソッドを呼び出した結果として競合状態が発生しないようにします。

于 2013-02-07T17:58:33.567 に答える