阻塞函数ReceiveFrom()

时间:2012-12-11 01:24:15

标签: c# sockets udp blocking windows-forms-designer

我正在通过UDP写聊天。当我尝试从控制台应用程序转到Windows窗体时,我遇到阻塞函数ReceiveFrom()的问题。当我尝试创建一个表单,并使用ReceiveFrom()单击一个用于监听传入数据包的按钮时,它只是阻止该程序。我写的是这样的:

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.
}

我知道我可以使用TCP,生活会更容易,但这样做是我的任务。 而且我知道我可以使用非阻塞的BeginReceiveFrom(),但我想知道是否有可能以某种方式使用阻塞函数在WF中进行监听。

2 个答案:

答案 0 :(得分:3)

您最好使用不同的方法并考虑更好的设计概念,例如MVC,但您可以将while循环包装在Task中。这将允许按钮单击事件完成并控制返回到您的应用程序。

答案 1 :(得分:0)

我发现使用async和await关键字可以解决阻塞函数和UI的问题。以下示例显示了解决方案:

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