1

我正在通过 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 中监听。

4

2 回答 2

3

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

于 2012-12-11T01:29:17.990 回答
0

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

 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];
            });
        }
    }
于 2012-12-25T18:41:39.517 回答