从另一个线程C#调用UI线程

时间:2019-02-17 15:29:22

标签: c# multithreading tcp async-await

我正在创建一个聊天应用程序,其中多个用户可以输入他们的消息并将其通过tcp(网络流)发送到服务器。

我有以下代码用于接收消息:

private void ReceiveData()
    {
        Task.Run(() =>
        {
            int bufferSize = 1024;
            string message = "";

            byte[] buffer = new byte[bufferSize];
            _NetworkStream = _TcpClient.GetStream();
            AddMessage("Connected!");

            while (true)
            {
                int readBytes = _NetworkStream.Read(buffer, 0, bufferSize);
                message = Encoding.ASCII.GetString(buffer, 0, readBytes);
                Console.WriteLine("I received a message: " + message);

                if (message.Equals("bye"))
                {
                    break;
                }

                AddMessage(message);
            }

            buffer = Encoding.ASCII.GetBytes("bye");
            _NetworkStream.Write(buffer, 0, buffer.Length);

            _NetworkStream.Close();
            _TcpClient.Close();

            AddMessage("Connection closed!");
        });
    }

现在,当我调用AddMessage(从另一个Thread调用,因此从另一个上下文调用)时,我的应用程序崩溃了。鉴于我的AddMessage代码,这很合乎逻辑:

private void AddMessage(string message)
    {
        this.ListBox_Messages.Items.Add(message);
    }

我的问题是,addmessage函数是否负责在ui线程或函数调用程序上执行此操作(在本例中为ReceiveData()),什么是实现它的最佳,最现代的方法?

提前谢谢!

1 个答案:

答案 0 :(得分:2)

您的老师真的教过了这些“现代方法”吗?!

告诉他或她,回到基础没有什么错

private void AddMessage(string message)
{
    if (this.ListBox_Messages.InvokeRequired)
    {
        this.ListBox_Messages.Invoke((MethodInvoker)delegate {
            this.ListBox_Messages.Items.Add(message);
        });
    }
    else
    {
        this.ListBox_Messages.Items.Add(message);
    }          
}

这很简单,而且可以正常工作。

作为我自己的计算机科学老师,我讨厌看到这类问题。让我想知道老师在做什么。

Teacher: "You must use this magical stuff that I haven't taught you yet!"

让您的老师从疑惑中受益,您还没有与我们共享此应用程序的任何要求吗?