线程间操作无效: 从不是创建控件“listBox1”的线程访问它
我用VS2005做个网络聊天程序,使用了多线程技术,但会出现这个异常,求高手们如何解决这个异常...原代码如下!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ChatServer
{
public partial class Form1 : Form
{
private IPAddress myIP = IPAddress.Parse( "127.0.0.1 ");
private IPEndPoint myserver;
private Socket sockets;
private Socket acsocket;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
myIP = IPAddress.Parse(textBox1.Text);
}
catch
{
MessageBox.Show( "你输入的IP地址格式不正确! ");
}
try
{
Thread thread = new Thread(new ThreadStart(accp));
thread.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void accp()
{
myserver = new IPEndPoint(myIP,Int32.Parse(textBox2.Text));
sockets = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sockets.Bind(myserver);
sockets.Listen(50);
listBox1.Items.Add( "主机 " + textBox1.Text + "端口 " + textBox2.Text + "开始监听....\r\n ");//为什么运行到这一部时会出现以上标题的这个异常呢?
while (true)
{
acsocket = sockets.Accept();
if (acsocket.Connected)
{
listBox1.Items.Add( "与客户建立连接... ");
Thread thread = new Thread(new ThreadStart(round));
thread.Start();
}
}
}
private void round()
{
while (true)
{
byte[] buffer=new byte[64];
NetworkStream netstream = new NetworkStream(acsocket);
netstream.Read(buffer,0,buffer.Length);
string rec = Encoding.BigEndianUnicode.GetString(buffer);
richTextBox1.AppendText(rec+ "\r\n ");
}
}
private void button2_Click(object sender, EventArgs e)
{
if (richTextBox2.Text == null)
{
MessageBox.Show( "不能发送空消息! ");
}
try
{
byte[] sendbyte = new byte[64];
string send = richTextBox2.Text + "\r\n ";
NetworkStream netstream = new NetworkStream(acsocket);
sendbyte = Encoding.BigEndianUnicode.GetBytes(send);
netstream.Write(sendbyte, 0, sendbyte.Length);
}
catch
{
MessageBox.Show( "连接没有建立!无法发送.. ");
}
}
private void button3_Click(object sender, EventArgs e)
{
try
{
sockets.Close();
listBox1.Items.Add( "主机 " + textBox1.Text + "端口 " + textBox2.Text + "停止监听...\r\n ");
}
catch
{
MessageBox.Show( "监听没有建立,无法关闭! ");
}
}
}
}
同样客户端的程序也会出现此类问题,要如何解决?
[解决办法]
在Form Load事件中加入
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
是最简单的方式
[解决办法]
UI上的控件不是线程安全的,所以跨线程的操作UI控件需要通过Invoke的方式:
private object m_SyncObjectForListBox = new object();
private void UpdateListBox(ListBox control, string text)
{
if (control.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(UpdateListBox);
this.Invoke(d, new object[] { control, text });
}
else
{
lock (m_SyncObjectForListBox)
{
control.Items.Add(text);
}
}
}