多线程环境中,如果多个线程同时尝试向同一个TCP客户端发送数据,添加同步机制
- 原代码
public async Task SendToClientAsync(TcpClient targetClient, byte[] data, int offset, int length)
{try{// 1. 检查客户端是否有效if (targetClient == null || !targetClient.Connected){Console.WriteLine("Cannot send: client is not connected");return;}// 2. 使用参数中的客户端对象NetworkStream stream = targetClient.GetStream();// 3. 异步写入数据await stream.WriteAsync(data, offset, length);Console.WriteLine("Data sent to client.");}catch (Exception ex){Console.WriteLine($"Error sending data to client: {ex.Message}");// 可添加更多错误处理逻辑,如重试或清理连接}
}
解决方案:添加同步机制
方案1:客户端级别的锁(推荐)
private readonly ConcurrentDictionary<TcpClient, SemaphoreSlim> clientLocks = new();public async Task SendToClientAsync(TcpClient targetClient, byte[] data, int offset, int length)
{// 获取或创建客户端专属锁var clientLock = clientLocks.GetOrAdd(targetClient, _ => new SemaphoreSlim(1, 1));await clientLock.WaitAsync();try{if (targetClient.Connected){NetworkStream stream = targetClient.GetStream();await stream.WriteAsync(data, offset, length);}}finally{clientLock.Release();}
}
方案2:全局锁(简单但性能低)
private readonly object sendLock = new object();public async Task SendToClientAsync(TcpClient targetClient, byte[] data, int offset, int length)
{lock (sendLock) // 全局同步锁{if (targetClient.Connected){NetworkStream stream = targetClient.GetStream();stream.Write(data, offset, length); // 注意:同步写入}}
}