2

我正在学习 c#,我想知道为什么我的代码不会在 ReceivePacket 区域的 DataGridView 中添加一行。它在 SendPacket 中有效,但在另一个中无效。目的是简单地向机器发送一个 UDP 数据包,在此先感谢。这是我的代码:

private void btnSend_Click(object sender, EventArgs e)
        {
            SendPacket();
        }
        private void btnReceiving_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(reciev));
            thread.Start();
        }    

UdpClient client = new UdpClient();

        public void SendPacket()
        {
            byte[] packet = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss:ff"));
            client.Send(packet, packet.Length, tbIP.Text, 444);
            dgvSend.Rows.Add(DateTime.Now.ToString("HH:mm:ss:ff"));
        }

        public void ReceivePacket(byte[] packet)
        {// it goes wrong here, because it gives a crossthread error
            dgvReceiv.Rows.Add(Encoding.ASCII.GetString(packet), DateTime.Now.ToString("HH:mm:ss:ff"));
        }

        public void reciev()
        {
            UdpClient client = new UdpClient(444);
            while (true)
            {
                IPEndPoint server = new IPEndPoint(IPAddress.Any, 0);
                byte[] packet = client.Receive(ref server);
                ReceivePacket(packet);
            }
        }

我使用这行代码而不是正常的(使用调用:))修复了它:

dgvReceiv.Invoke(new MethodInvoker(delegate { dgvReceiv.Rows.Add(Encoding.ASCII.GetString(packet), DateTime.Now.ToString("HH:mm:ss:ff")); }));
4

2 回答 2

2

在这里,您将看到使用委托从其他线程调用在主线程上创建的控件上的操作的示例。

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

于 2012-09-21T07:46:19.040 回答
1

问题是您试图在主 GUI 线程之外的另一个线程上创建 GUI 元素(表单)。您只能在 GUI 线程上创建 GUI 元素。别的什么都行不通。

您应该在辅助线程中接收数据,然后将其复制到您的 GUI 线程,以将其放入 GUI 元素中。我认为有一个函数Control.Invoke是一个委托,它将在创建控件的线程上调用一个函数,您可以使用该函数从辅助线程调用以实际填充您的表单或任何控件。

于 2012-09-21T07:43:51.507 回答