无效的线程操作,调用方法不起作用 [英] Invalid thread operation, invoke method does not work

查看:64
本文介绍了无效的线程操作,调用方法不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在线聊天代码,系统上有一个已登录用户的列表。在listBox中添加用户名时出现问题错误如下:无效的线程操作:控制从不是创建它的线程访问的'lbClients'。



我尝试了Invoke方法,但它也没有用。使用Invoke方法,服务器将用户添加到列表中,但是当用户断开连接时,登录到服务器的用户列表不会刷新。可以做些什么?



代码:



I have an online chat code, there is a list of logged in users on the system. There is a problem adding the users name in the listBox The error is as follows: Invalid thread operation: control 'lbClients' accessed from a thread that is not the one in which it was created.

I tried the Invoke method, but it also did not work. With the Invoke method, the server adds the user to the list, but when the user disconnects, the list of users logged on to the server does not refresh. What can be done?

Code:

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;
    	}





我的尝试:





What I have tried:

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
        }





和:





and:

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;
        }

推荐答案

将新的动作添加到并发队列;启动后台工作人员清空队列并更新报告进度事件中的列表框。



如果BGW已经运行,只需添加到队列。
Add any new "actions" to a concurrent queue; start a background worker to empty the queue and update the listbox in the reporting progress event.

If the BGW is already running, just add to queue.


这篇关于无效的线程操作,调用方法不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆