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 ループを Task にラップすることもできます。これにより、ボタン クリック イベントが完了し、コントロールがアプリケーションに返されます。

于 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 に答える