我得到一个Exception InvalidOperationException,而我没有';我不知道为什么

本文关键字:为什么 我不知道 InvalidOperationException 一个 Exception | 更新日期: 2023-09-27 18:00:44

这是与多用户聊天的一部分,我想在循环中反序列化,这样我为每个用户收到的每条消息都可以发布(这是服务器端)

public class ServerDLL
{
    public TcpClient client { get; set; }
    public TcpListener listner { get; set; }
    public List<NetworkStream> clientStream = new List<NetworkStream>();
    public List<TcpClient> clientsList = new List<TcpClient>();
    string clientMsg;
    BinaryFormatter formatter = new BinaryFormatter();
    private object clientListLock = new object();
    public void startConnection()
    {
        Thread listnerThread = new Thread(ListnerFunc);
        listner.Start();
        listnerThread.Start();
        Thread waitForMeesage = new Thread(WaiterFunc);
        waitForMeesage.Start();
    }
    public void ListnerFunc()
    {
        while (true)
        {
            client = listner.AcceptTcpClient();
            clientStream.Add(client.GetStream());
            if (client.Connected)
            {
                lock (clientListLock)
                {
                    clientsList.Add(client);
                }
            }
        }
    }
    public void WaiterFunc()
    {
        while (true)
        {
            lock (clientListLock)
            {
                foreach (NetworkStream stream in clientStream)
                {
                    if (stream != null)
                    {
                        clientMsg = formatter.Deserialize(stream).ToString();
                    }
                }
            }
        }
    }

现在,当我从客户端发送消息时,异常弹出。。

我得到一个Exception InvalidOperationException,而我没有';我不知道为什么

首先,您确实应该在WaiterFunc()中放入某种等待。像那样旋转CPU不是一个好主意。

也就是说,在clientStream集合中有一个跨线程共享资源。您不能在枚举期间修改集合(while循环经常这样做),从而引发异常。

您需要锁定访问此列表的权限:

private object clientListLock = new object();
public void ListnerFunc()
{
    while (true)
    {
        client = listner.AcceptTcpClient();
        lock(clientListLock)
        {
           clientStream.Add(client.GetStream());
           if (client.Connected)
           {
               clientsList.Add(client);
           }
        }
    }
}
public void WaiterFunc()
{
    while (true)
    {
        lock (clientListLock)
        {
           foreach (NetworkStream stream in clientStream)
           {
               clientMsg = formatter.Deserialize(stream).ToString();
           }
        }
    }
}