c#WPF窗口不';在While循环期间不显示。UDP

c#WPF窗口不';在While循环期间不显示。UDP,c#,wpf,udp,C#,Wpf,Udp,我不熟悉C#,正在尝试UDP阅读器。我每秒都在发送连续的“测试”短信。但是,主窗口和tex框根本不会出现。我注意到,当我引入while循环时,这种情况总是发生。如果没有while循环,则会出现窗口/文本框,并将传入消息“text”写入一次。我有一个单独的程序不断发送UDP消息 我被困在这里了。带有while循环的代码在控制台中工作正常 namespace WpfApp2 { /// <summary> /// Interaction logic for MainWin

我不熟悉C#,正在尝试UDP阅读器。我每秒都在发送连续的“测试”短信。但是,主窗口和tex框根本不会出现。我注意到,当我引入while循环时,这种情况总是发生。如果没有while循环,则会出现窗口/文本框,并将传入消息“text”写入一次。我有一个单独的程序不断发送UDP消息

我被困在这里了。带有while循环的代码在控制台中工作正常

namespace WpfApp2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            bool done = false;
            var receivePort = 11000;

            InitializeComponent();

            UdpClient readerClient = new UdpClient(receivePort);


            while (!done)
            {

                var remoteEP = new IPEndPoint(IPAddress.Any, receivePort);

                byte[] bytesReceived = readerClient.Receive(ref remoteEP);

                tb.AppendText(Encoding.ASCII.GetString(bytesReceived));

            }
        }
    }
}
名称空间WpfApp2
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
bool done=false;
var接收端口=11000;
初始化组件();
UdpClient readerClient=新的UdpClient(接收端口);
而(!完成)
{
var remoteEP=新的IPEndPoint(IPAddress.Any,receivePort);
字节[]bytesReceived=readerClient.Receive(参考remoteEP);
AppendText(Encoding.ASCII.GetString(bytesReceived));
}
}
}
}

重画控件的更新通过消息完成。必须处理这些消息(它发生在后台)。您面临的问题是,由于while循环,无法处理这些消息。whileloop/Receive阻塞当前线程

最好的做法是将UDP代码移动到单独的线程/任务

你可以试试这样的

下面是一个使用单独线程的示例:

public partial class MainWindow : Window
{
    private UdpClient _readerClient;
    private Thread _udpThread;
    private ManualResetEvent _done = new ManualResetEvent(false);
    private int _receivePort;

    public MainWindow()
    {
        _receivePort = 11000;

        InitializeComponent();

        _readerClient = new UdpClient(_receivePort);

        _udpThread = new Thread(UDPHandler);
    }


    private void UDPHandler()
    {

        while (!_done.WaitOne(0))
        {

            var remoteEP = new IPEndPoint(IPAddress.Any, _receivePort);

            byte[] bytesReceived = _readerClient.Receive(ref remoteEP);

            // since this is (probably) NOT the UI thread, post it to it's dispatcher. (WPF)
            // this makes multithreading harder...
            tb.Dispatcher.BeginInvoke(new Action(() =>
            {
                tb.AppendText(Encoding.ASCII.GetString(bytesReceived));
            }));

        }
    }

    private void Window_Closed(object sender, EventArgs e)
    {
        // stop the while loop
        _done.Set();
        // wait until the thread finished.
        _udpThread.Join();
    }
}

您应该添加一些异常处理等。。这只是一个示例。

您的问题是,您正在使用并阻止WPF也希望用于绘制其元素的主线程

所以WPF必须等待循环完成

C#提供的是异步/等待 (未经测试)

名称空间WpfApp2
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
//异步任务在这里很重要
公共异步任务DoStuffAsync()
{
bool done=false;
var接收端口=11000;
UdpClient readerClient=新的UdpClient(接收端口);
var remoteEP=新的IPEndPoint(IPAddress.Any,receivePort);
readerClient.Connect(remoteEP);
而(!完成)
{
//我们在这里等待结果
//同时,主线程没有阻塞,WPF可以完成其工作
//在模块中查找…异步函数,这些函数提供了值得期待的功能
byte[]bytesReceived=等待readerClient.ReceiveAsync();
AppendText(Encoding.ASCII.GetString(bytesReceived));
}
}
公共主窗口()
{
初始化组件();
//这里我们调用一个异步函数。
//这里的问题是:由于异步的性质,您无法捕获异常
//但您可以设置异步函数失败时执行的代码
DoStuffAsync().ContinueWith(t=>
{
//异常在t中
},TaskContinuationOptions.OnlyOnFaulted);
}
}
}

注意:本示例旨在进行尽可能少的更改,这不是最佳做法。

谢谢您的评论。我仍然努力让它工作,但必须学习相当多。我不确定这是否是最佳实践代码,但是否适用于我的个人项目。我仍然有所有的豁免要做,但很高兴,因为我几乎要放弃了

    public partial class pUDP : Page
{
    public pUDP()
    {
        InitializeComponent();

        
    }

    private async void btnConnect_Click(object sender, RoutedEventArgs e)
    {

        var port = 11000;
        bool done = false;
        UdpClient listener = new UdpClient(port);

        IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Any, port);


        while (!done)
            {
             
                byte[] receivedData = await Task.Run(() => listener.Receive(ref listenEndPoint));
                tbRead.AppendText(Encoding.ASCII.GetString(receivedData));                  

            }

        listener.Close();


    }
}

}

当listener.Receive()上发生异常时,您将遇到问题。
    public partial class pUDP : Page
{
    public pUDP()
    {
        InitializeComponent();

        
    }

    private async void btnConnect_Click(object sender, RoutedEventArgs e)
    {

        var port = 11000;
        bool done = false;
        UdpClient listener = new UdpClient(port);

        IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Any, port);


        while (!done)
            {
             
                byte[] receivedData = await Task.Run(() => listener.Receive(ref listenEndPoint));
                tbRead.AppendText(Encoding.ASCII.GetString(receivedData));                  

            }

        listener.Close();


    }
}