[英]Safe Multi-thread access in C#
I am trying to implement a chat. 我正在尝试进行聊天。 I have taken a code here 我在这里取了一个代码
When I send messages I have an error: 发送邮件时出现错误:
Control 'ListMessage' name accessed from a thread other than the thread it was created on. 控件“ ListMessage”的名称是从不是在其上创建线程的线程访问的。
where ListMessage is a ListView added with Visual Studio. 其中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());
}
}
I have tried to use Invoke as described here but I have errors 我尝试按照此处所述使用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 are: 错误是:
My questions: 我的问题:
Yes, the approach is quite correct, but you did miss a few things with the implementation. 是的,这种方法是正确的,但是您在实现中确实错过了一些事情。
The AddItemSafe
method is just a method inside your form descendant class, not a method on listMessage
(whatever type that may be). 该AddItemSafe
方法只是你的形式派生类中的方法,而不是一种方法listMessage
(任何类型而定)。 So when you call that, you only have to specify the method name and the parameter and not call it on an another object instance. 因此,当您调用它时,只需指定方法名称和参数,而无需在另一个对象实例上调用它。
...
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);
...
Then, inside the AddItemSafe method, you do exactly what you would do in a single threaded environment, ie add to the items of listMessage
. 然后,在AddItemSafe方法内部,您可以完全执行在单线程环境中的操作,即添加到listMessage
的项中。 If invoke is required, then you wrap the whole thing into a delegate. 如果需要invoke,则将整个内容包装到一个委托中。
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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.