Недопустимая операция потока, метод invoke не работает
У меня есть код онлайн-чата, есть список вошедших в систему пользователей. Существует проблема добавления имени пользователя в поле списка ошибка выглядит следующим образом: недопустимая операция потока: управление 'lbClients' осуществляется из потока, который не является тем, в котором он был создан.
Я попробовал вызвать метод, но он также не сработал. С помощью метода Invoke сервер добавляет пользователя в список, но когда пользователь отключается, список пользователей, вошедших на сервер, не обновляется. Что можно сделать?
Код:
public void StartListening() { listener = new TcpListener(listenport); listener.Start(); while (true) { try { Socket s = listener.AcceptSocket(); clientsocket = s; clientservice = new Thread(new ThreadStart(ServiceClient)); clientservice.Start(); } catch(Exception e) { Console.WriteLine(e.ToString() ); } } //listener.Stop(); } public void ServiceClient() { Socket client = clientsocket; bool keepalive = true; while (keepalive) { Byte[] buffer = new Byte[1024]; client.Receive(buffer); string clientcommand = System.Text.Encoding.ASCII.GetString(buffer); string[] tokens = clientcommand.Split(new Char[]{'|'}); Console.WriteLine(clientcommand); if (tokens[0] == "CONN") { for(int n=0; n<clients.Count; n++) { Client cl = (Client)clients[n]; SendToClient(cl, "JOIN|" + tokens[1]); } EndPoint ep = client.RemoteEndPoint; //string add = ep.ToString(); Client c = new Client(tokens[1], ep, clientservice, client); this.Invoke(new Action(() => clients.Add(c))); string message = "LIST|" + GetChatterList() +"\r\n"; SendToClient(c, message); try { lbClients.Items.Add(c); } catch (Exception e) { MessageBox.Show(e.Message); } } else if (tokens[0] == "CHAT") { for(int n=0; n<clients.Count; n++) { Client cl = (Client)clients[n]; SendToClient(cl, clientcommand); } } else if (tokens[0] == "PRIV") { string destclient = tokens[3]; for(int n=0; n<clients.Count; n++) { Client cl = (Client)clients[n]; if(cl.Name.CompareTo(tokens[3]) == 0) SendToClient(cl, clientcommand); if(cl.Name.CompareTo(tokens[1]) == 0) SendToClient(cl, clientcommand); } } else if (tokens[0] == "GONE") { int remove = 0; bool found = false; int c = clients.Count; for(int n=0; n<c; n++) { Client cl = (Client)clients[n]; SendToClient(cl, clientcommand); if(cl.Name.CompareTo(tokens[1]) == 0) { remove = n; found = true; lbClients.Items.Remove(cl); //lbClients.Items.Remove(cl.Name + " : " + cl.Host.ToString()); } } if(found) this.Invoke(new Action(() => clients.RemoveAt(remove))); client.Close(); keepalive = false; } else { int remove = 0; bool found = false; int c = clients.Count; for (int n = 0; n < c; n++) { Client cl = (Client)clients[n]; //SendToClient(cl, clientcommand); if (cl.Name.CompareTo(tokens[1]) == 0) { remove = n; found = true; lbClients.Items.Remove(cl); //lbClients.Items.Remove(cl.Name + " : " + cl.Host.ToString()); } } if (found) clients.RemoveAt(remove); client.Close(); keepalive = false; } } } public void SendToClient(Client cl, string message) { try{ byte[] buffer = System.Text.Encoding.ASCII.GetBytes(message.ToCharArray()); cl.Sock.Send(buffer,buffer.Length,0); } catch(Exception e){ cl.Sock.Close(); cl.CLThread.Abort(); clients.Remove(cl); lbClients.Items.Remove(cl.Name + " : " + cl.Host.ToString()); //MessageBox.Show("Could not reach " + cl.Name + " - disconnected","Error", //MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } public string GetChatterList() { string chatters = ""; for(int n=0; n<clients.Count; n++) { Client cl = (Client)clients[n]; chatters += cl.Name; chatters += "|"; } chatters.Trim(new char[]{'|'}); return chatters; }
Что я уже пробовал:
if (tokens[0] == "CONN") { for (int n = 0; n < clients.Count; n++) { Client cl = (Client)clients[n]; SendToClient(cl, "JOIN|" + tokens[1]); } EndPoint ep = client.RemoteEndPoint; //string add = ep.ToString(); Client c = new Client(tokens[1], ep, clientservice, client); this.Invoke(new Action(() => clients.Add(c))); string message = "LIST|" + GetChatterList() + "\r\n"; SendToClient(c, message); this.Invoke(new Action(() => lbClients.Items.Add(c))); //NEW CODE //lbClients.Items.Add(c); //OLD CODE }
и:
else if (tokens[0] == "GONE") { int remove = 0; bool found = false; int c = clients.Count; for (int n = 0; n < c; n++) { Client cl = (Client)clients[n]; SendToClient(cl, clientcommand); if (cl.Name.CompareTo(tokens[1]) == 0) { remove = n; found = true; this.Invoke(new Action(() => lbClients.Items.Remove(cl))); //NEW CODE //lbClients.Items.Remove(cl); //OLD CODE } } if (found) this.Invoke(new Action(() => clients.RemoveAt(remove))); client.Close(); keepalive = false; }
F-ES Sitecore
Вы удалите таким же образом можно добавить с помощью вызова.
Phenton
Но это не работает в моем коде, сервер не удаляет отключенного пользователя...