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