Я получаю исключение InvalidOperationException, и я не знаю, почему
Это часть чата с несколькими пользователями, и я хочу десериализовать в цикле, чтобы каждое сообщение, которое я получаю, для каждого пользователя, которого я могу опубликовать (это на стороне сервера)
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();
}
}
}
}
}
теперь исключение выскакивает, когда я отправляю сообщение от клиента..
1 ответ
Во-первых, вам действительно нужно подождать в WaiterFunc(). Вращать процессор, как это, не очень хорошая идея.
При этом у вас есть общий ресурс с несколькими потоками в 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();
}
}
}
}