新しいスレッドを生成し、ループで UDP パケットのリッスンと待機を開始するこのフォームがあります。必要なのは、受信したバイト数で UI を更新し続けることです。
そのために、パケットが受信されるとすぐに発生するイベントをセットアップし、受信したバイト数を引数として渡します。UI スレッドで実行していないため、UI を直接更新することはできません。これが私が現在行っていることです:
private void EVENTHANDLER_UpdateTransferProgress(long receivedBytes) {
if(InvokeRequired) {
Invoke(new MethodInvoker(() => {
totalReceivedBytes += receivedBytes;
Label.Text = totalReceivedBytes.ToString("##,0");
}));
}
}
しかし、これはまだパケット受信ループと同じスレッドで実行されており、EVENTHANDLER_UpdateTransferProgress
このメソッドが戻るまで、そのループには戻らず、別のパケットを待ちます。
私の質問は、基本的に上記の方法の次の行に関するものです。
Label.Text = totalReceivedBytes.ToString("##,0");
このように UI を更新すると、パケットの受信が遅くなります。その行を削除 (またはコメント) すると、パケットの受信がはるかに高速になります。
どうすればこの問題を解決できますか? より多くのスレッドが重要だと思いますが、この状況でそれらを適切に実装する方法がわかりません....NET 2.0 で Windows フォームを使用しています。
編集:
私の以前のテストでは、上記は真実であるように見え、実際にはある程度そうである可能性があります. しかし、もう少しテストした後、問題は全体にあるInvoke(new MethodInvoker(() => { ... }));
ことに気付きました。それを削除して (もちろん UI は更新されません) EVENTHANDLER_UpdateTransferProgress
、イベントを発生させ続けると、パケットの受信がはるかに高速になります。
Invoke()
イベント ハンドラをまったく呼び出さずに、平均で約 1.5 秒かかるファイルの受信をテストしました。UI のコントロールを更新したり操作を行ったりしなくても (つまり、匿名メソッドの本体が空だった場合)、イベント ハンドラーを呼び出すInvoke()
と、約 5.5 秒と、はるかに長い時間がかかりました。大きな違いであることがわかります。
これを改善する方法はありますか?