[英]Safe Multi-thread access in C#
我正在嘗試進行聊天。 我在這里取了一個代碼
發送郵件時出現錯誤:
控件“ 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());
}
}
我嘗試按照此處所述使用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);
錯誤是:
我的問題:
是的,這種方法是正確的,但是您在實現中確實錯過了一些事情。
該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
的項中。 如果需要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.