我正在通过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中进行监听。
答案 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];
});
}
}