![](/img/trans.png)
[英]WPF | C# - When WindowStyle = “None” and the window is maximized the Task Bar doesn't show up
[英]c# WPF Window doesn't show during While Loop. UDP
我是 C# 的新手,正在嘗試使用 UDP 閱讀器。 我每秒都在發送連續的“測試”短信。 但是主 Window 和 tex 框根本沒有出現。 我注意到當我引入一個while循環時總是會發生這種情況。 如果沒有 while 循環,窗口/文本框會出現並寫入一次傳入消息“文本”。 我有一個單獨的程序不斷發送 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));
}
}
}
}
重繪控件的更新是通過消息完成的。 必須處理這些消息(它發生在后台)。 您面臨的問題是由於 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# 提供的是異步/等待(未經測試)
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
// async Task is important here
public async Task DoStuffAsync()
{
bool done = false;
var receivePort = 11000;
UdpClient readerClient = new UdpClient(receivePort);
var remoteEP = new IPEndPoint(IPAddress.Any, receivePort);
readerClient.Connect(remoteEP);
while (!done)
{
// Here we await the result
// meanwhile the main thread is not blocked and WPF can do its work
// look for ...Async functions in your modules that provide awaitable functionality
byte[] bytesReceived = await readerClient.ReceiveAsync();
tb.AppendText(Encoding.ASCII.GetString(bytesReceived));
}
}
public MainWindow()
{
InitializeComponent();
// Here we call an async function.
// Problem here: You cannot catch exceptions, because of asyncs nature
// But you can set code that is executed when the async function fails
DoStuffAsync().ContinueWith(t =>
{
// Exception is in t.Exception
}, 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();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.