Search code examples
c#socketsudpblockingwindows-forms-designer

Blocking function ReceiveFrom()


I'm writing a chat over UDP. I faced a problem with a blocking function ReceiveFrom(), when I tried to go from Console Application to Windows Forms. When I try to create a form, and click a button for the listening incoming packets with ReceiveFrom() it's just blocks the program. I'm writing something like this:

private void Listen_button_click(object sender, EventArgs e)
{
      while(true){
         ReceiveFrom(buf, ref clientEP);
         data = buf.ToData(); //convert from bytes to string.
         displayMessageDelegate(data);
         packet = new Packet(acknowlegment);//acknowledgment that packet was received.
         ack = packet.ToStream();
         SendTo(ack, clientEP);//send ack, so client knows everything is ok.
}

I know that I could use TCP, and life would be much more easier, but it's my task to do this way. And I know that I could use non-blocking BeginReceiveFrom(), but I want to know if it is possible somehow to listen in WF using blocking function.


Solution

  • I found out that the problem of blocking functions and UI is solved by using async and await keywords. Following example shows the solution:

     private async void Listen_button_click(object sender, EventArgs e)
        {
            while (true)
            {
                await Task.Run(() =>
                {
                    Thread.Sleep(10000);
                    buf = new byte[1024];
                    int rcv = clientSock.ReceiveFrom(buf, ref servEP);
                    msg = Encoding.ASCII.GetString(buf, 0, rcv);
    
                    this.Invoke((Action)delegate
                    {
                        this.dialogTextBox.Text += rcv;
                        this.dialogTextBox.Text += string.Format("server: {0}, rcv: {1}", 
                               msg, rcv) + Environment.NewLine;
                        for (int i = 0; i < buf.Length; i++)
                        {
                            this.dialogTextBox.Text += buf[i].ToString();
                        }
                    });
                    buf = new byte[1024];
                });
            }
        }