我正在尝试实施聊天。我已经采用了代码here
当我发送消息时,我有一个错误:
Control' ListMessage'从除以外的线程访问的名称 线程是在它上面创建的。
其中ListMessage是使用Visual Studio添加的ListView。
private void buttonSend_Click(object sender, EventArgs e)
{
//convert string message to byte[]
ASCIIEncoding aEncoding = new ASCIIEncoding();
byte[] sendingMessage = new byte[1500];
sendingMessage = aEncoding.GetBytes(textMessage.Text);
//sending the encoded message
sck.Send(sendingMessage);
//adding to the list box
listMessage.Items.Add("Me:" + textMessage.Text);
textMessage.Text = "";
}
private void MessageCallBack(IAsyncResult aResult)
{
try
{
byte[] receivedData = new byte[1500];
receivedData = (byte[])aResult.AsyncState;
//converting byte[] to string
ASCIIEncoding aEncoding = new ASCIIEncoding();
string receivedMessage = aEncoding.GetString(receivedData);
//Adding this message into list box
///// error is given in the following line/////
listMessage.Items.Add("Friend:" + receivedMessage);
buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
我试图按照here所述使用Invoke,但我有错误
private void MessageCallBack(IAsyncResult aResult)
{
try
{
byte[] receivedData = new byte[1500];
receivedData = (byte[])aResult.AsyncState;
//converting byte[] to string
ASCIIEncoding aEncoding = new ASCIIEncoding();
string receivedMessage = aEncoding.GetString(receivedData);
//Adding this message into list box
//listMessage.Items.Add("Friend:" + receivedMessage);
listMessage.AddItemSafe("Friend:" + receivedMessage);
buffer = new byte[1500];
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void AddItemSafe(string text)
{
if (this.InvokeRequired)
{
AddItemSafeCallback a = new AddItemSafeCallback(AddItemSafe);
this.Invoke(a, new object[] { text });
}
else
{
this.Items.Add(text);
}
}
delegate void AddItemSafeCallback(string text);
Erros是:
我的问题:
答案 0 :(得分:3)
是的,这种方法非常正确,但您确实错过了实施的一些内容。
AddItemSafe
方法只是表单后代类中的一个方法,而不是listMessage
上的方法(可能是任何类型)。因此,当您调用它时,您只需指定方法名称和参数,而不是在另一个对象实例上调用它。
...
ASCIIEncoding aEncoding = new ASCIIEncoding();
string receivedMessage = aEncoding.GetString(receivedData);
//Adding this message into list box
//listMessage.Items.Add("Friend:" + receivedMessage);
// !!!!Note difference here:
AddItemSafe("Friend:" + receivedMessage);
...
然后,在AddItemSafe方法中,您完全按照在单线程环境中执行的操作,即添加到listMessage
的项目。如果需要调用,则将整个事物包装到委托中。
private void AddItemSafe(string text)
{
if (this.InvokeRequired)
{
AddItemSafeCallback a = new AddItemSafeCallback(AddItemSafe);
this.Invoke(a, new object[] { text });
}
else
{
// !!!!Note difference here:
listmessage.Items.Add(text);
}
}