VB.NET[跨线程操作无效:从线程访问的控件';txtinomingtext';….]

VB.NET[跨线程操作无效:从线程访问的控件';txtinomingtext';….],vb.net,multithreading,visual-studio,sockets,visual-studio-2012,Vb.net,Multithreading,Visual Studio,Sockets,Visual Studio 2012,我是VB.NET的初学者,请耐心听我说 我在VB.NET中下载了一个多客户端TCP-IP套接字服务器客户端应用程序。服务器可以很好地侦听,但客户端遇到以下异常: “跨线程操作无效:控件'txtIncomingText'是从创建它的线程以外的线程访问的。” 如果你们能帮我修改代码的版本,我将不胜感激。多谢各位 '----客户端代码------- 导入System.Windows.Forms 导入System.Collections.Generic 导入System.ComponentModel 导

我是VB.NET的初学者,请耐心听我说

我在VB.NET中下载了一个多客户端TCP-IP套接字服务器客户端应用程序。服务器可以很好地侦听,但客户端遇到以下异常:

“跨线程操作无效:控件'txtIncomingText'是从创建它的线程以外的线程访问的。”

如果你们能帮我修改代码的版本,我将不胜感激。多谢各位

'----客户端代码-------

导入System.Windows.Forms
导入System.Collections.Generic
导入System.ComponentModel
导入系统数据
导入系统。绘图
导入系统
导入系统.Net
导入System.Net.Sockets
导入系统文本
导入系统线程
公共类FRM客户端
继承形式
私有子frmClient_Load(发送方作为System.Object,e作为System.EventArgs)处理MyBase.Load
端接头
Private _clientSocket作为新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp)
公共分新()
初始化组件()
端接头
Private receivedBuf As Byte()=新字节(1023){}
专用thr As线程
专用子接收数据(ar作为IAsyncResult)
作为套接字的Dim套接字=DirectCast(ar.AsyncState,套接字)
作为整数接收的Dim=socket.EndReceive(ar)
Dim dataBuf As Byte()=新字节(已接收-1){
Array.Copy(receivedBuf、dataBuf、received)
'这两行遇到错误->>>
Text=(Encoding.ASCII.GetString(dataBuf))
rbChat.Text=“\n服务器:”+txtinomingtext.Text
_clientSocket.BeginReceive(receivedBuf,0,receivedBuf.Length,SocketFlags.None,新异步回调(ReceiveData的地址),\u clientSocket)
端接头
私有子SendLoop()
虽然是真的
'Console.WriteLine(“输入请求:”);
'string req=Console.ReadLine();
'byte[]buffer=Encoding.ASCII.GetBytes(req);
'_clientSocket.Send(缓冲区);
Dim receivedBuf As Byte()=新字节(1023){}
Dim rev As Integer=\u clientSocket.Receive(receivedBuf)
如果版本0,则
作为字节()的Dim数据=新字节(rev-1){
Array.Copy(receivedBuf、data、rev)
lbStt.Text=(“接收:”+Encoding.ASCII.GetString(数据))
rbChat.AppendText(vbLf和“服务器:”+Encoding.ASCII.GetString(数据))
其他的
_clientSocket.Close()
如果结束
结束时
端接头
专用子环连接()
以整数=0的形式调整尝试次数
未连接时\u clientSocket.Connected
尝试
尝试次数+=1
_clientSocket.Connect(IPAddress.Loopback,420)
捕获generatedExceptionName作为SocketException
'Console.Clear();
lbStt.Text=(“连接尝试次数:+尝试次数.ToString())
结束尝试
结束时
lbStt.Text=(“已连接!”)
端接头
私有子BTN发送\单击(发送者作为System.Object,e作为System.EventArgs)处理BTN发送。单击
如果_clientSocket.Connected,则
作为字节()的Dim缓冲区=Encoding.ASCII.GetBytes(txtText.Text)
_clientSocket.Send(缓冲区)
rbChat.AppendText(“客户端:+txtText.Text”)
如果结束
端接头
私有子btnConnect_Click(发送方作为System.Object,e作为System.EventArgs)处理btnConnect。单击
LoopConnect()
'SendLoop();
_clientSocket.BeginReceive(receivedBuf,0,receivedBuf.Length,SocketFlags.None,新的AsyncCallback(ReceiveData的地址),_clientSocket)缓冲区为Byte()=Encoding.ASCII.GetBytes(@“+txtName.Text)
_clientSocket.Send(缓冲区)
端接头
末级

那么,您应该调用控件线程上的调用。这是一个快速而肮脏的解决方案

Dim message = Encoding.ASCII.GetString(dataBuf)
txtIncomingText.Invoke(Sub() txtIncomingText.Text = message)
rbChat.Invoke(Sub() rbChat.Text = Environment.NewLine & "Server: " & message)
但您应该首先检查是否需要调用。看

另外,
“\n”
不是在vb.net中创建新行的方式(您是否从c#复制了此代码?)


+
不是在vb.net中连接字符串的方式(请参见上面的括号)。

错误消息的哪一部分让您感到困惑?这很清楚-您无法从非UI线程访问控件。可能的控件副本必须是vb.net副本。@djv不确定是否有,但它们都是.net语言,都是出于相同的原因,并且都使用委托调用进行了类似的修复。我100%同意,但有些vb.net用户无法阅读c。哇,非常感谢!!成功了!!我如何投票给你的答案?你猜对了,我下载了这段代码,并使用一些转换网站将其从C#转换为VB.NET:)
Dim message = Encoding.ASCII.GetString(dataBuf)
txtIncomingText.Invoke(Sub() txtIncomingText.Text = message)
rbChat.Invoke(Sub() rbChat.Text = Environment.NewLine & "Server: " & message)