代码之家  ›  专栏  ›  技术社区  ›  droledenom

C中的安全多线程访问#

  •  0
  • droledenom  · 技术社区  · 7 年前

    我正在尝试实现聊天。我带了密码 here

    从除 创建它的线程。

    其中,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

            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);
    

    • “ListBox”不包含“AddItemSafe”的定义,也不包含扩展methode。”可以找到AddItemSafe“接受类型为“ListBox”的第一个参数(您是否缺少using指令或程序集引用”
    • 可以找到“ListBox”(您是否缺少using指令或 程序集引用'

    • 你认为我试图解决最初问题的方法是好的吗
    • 如果是,我尝试的解决方案有什么问题
    1 回复  |  直到 7 年前
        1
  •  3
  •   Akos Nagy    7 年前

    是的,这种方法非常正确,但在实现过程中确实遗漏了一些东西。

    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方法中,您可以完全像在单线程环境中一样执行操作,即添加到 列表消息

    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);
      }
    }