Reputation:
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
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
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