user944197
user944197

Reputation:

c# Thread won't add Row to DataGridView CrossThreadError

I am learning c# and I would like to know why my code won't add a row to my DataGridView in the ReceivePacket area. It works in the SendPacket but not in the other. The purpose is to simply send a UDP packet to a machine, thanks in advance. Here is my code:

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

I fixed it using this line of code instead of the normal (with the invoke :) ):

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

Upvotes: 2

Views: 1752

Answers (2)

Tomq
Tomq

Reputation: 1125

Here you go example of using delegates to invoke actions from other threads on controls created on main thread.

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

Upvotes: 2

Tony The Lion
Tony The Lion

Reputation: 63290

The problem is that you're attempting to create a GUI element (a form) on another thread than the main GUI thread. You can only create GUI elements on the GUI thread. Anything else doesn't work.

You should receive the data in your secondary thread, and then copy it over to your GUI thread, to put it inside a GUI element. I think there's a function Control.Invoke that is a delegate that will invoke a function on the thread the Control was created on, which you could use to call from your secondary thread to actually populate your form or whatever control.

Upvotes: 1

Related Questions