【问题标题】:Threadsafe class to send messages through socketThreadsafe 类通过套接字发送消息
【发布时间】:2013-02-07 17:42:48
【问题描述】:

我正在尝试实现一个通过套接字向服务器发送消息的模块。它将在多线程环境中使用,因此这个“客户端”对象在线程之间共享。 我的问题是我应该在 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);
        //}
    }
}

【问题讨论】:

  • 您的MessengerClient 是否为每个客户端实例化?
  • 是的,这是我的问题。如果您需要传输是线程安全的,您是否有多个对象使用同一个连接?看来您应该有一个管理网络流量的“连接管理器”对象。
  • 这只会实例化一次,其他一些对象(来自不同线程)将通过 SendMessage 方法发送消息。
  • @tuta4 - 如果它可以为您节省一点时间,请查看网络库 networkcomms.net。它是完全线程安全的,您可能遇到的大多数问题都已经解决。最好的起点是这里,networkcomms.net/…

标签: c# .net multithreading sockets


【解决方案1】:

根据the documentation for Socket

线程安全:

这个类的实例是线程安全的。

所以虽然thread safe is a somewhat ambiguous term,在这种情况下,它的意思是这个类的方法,包括实例方法,从你的角度来看是原子的。您可以调用一个方法并知道它看起来好像完全在其他线程中同时调用的任何方法之前或完全之后运行。它永远不会执行一个方法的一半,然后另一个,然后完成第一个(除非它可以保证在拆分时输出与使它们完全原子化相同)。

所以,简而言之,您不需要添加lockSocket 类将确保不存在由于同时[或前后]从多个线程调用方法而导致的竞争条件。

【讨论】:

    最近更新 更多