1
I have an online chat code, in it there is a list of logged in users on the system. There is a problem when adding the name of users on listBox
; The error is as follows: Operação entre threads inválida: controle 'lbClients' acessado de um thread que não é aquele no qual foi criado.
Codes:
public Principal()
{
InitializeComponent();
clients = new ArrayList();
processor = new Thread(new ThreadStart(StartListening));
processor.Start();
}
public void StartListening()
{
listener = new TcpListener(listenport);
listener.Start();
while (true)
{
try
{
Socket s = listener.AcceptSocket();
clientsocket = s;
clientservice = new Thread(new ThreadStart(ServiceClient));
//this.Invoke(new Action(() => ServiceClient()));
clientservice.Start();
//Iniciar += new EventHandler(ServiceClient);
//Iniciar.Invoke();
}
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);
lbClients.Items.Add(c);
}
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);
}
}
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);
}
}
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());
}
}
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;
}
Specifically in this part of the code that adds the user to the list:
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);
lbClients.Items.Add(c);
}
And this one, which removes the user from the list:
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);
}
}
if (found)
this.Invoke(new Action(() => clients.RemoveAt(remove)));
client.Close();
keepalive = false;
}
How to get around that mistake once I tried the Invoke
but it didn’t work?