私は新しいスレッドを生成し、リスニングしてループ内のUDPパケットを待つこのフォームを持っています。私が必要とするのは、受け取ったバイト数でUIを更新し続けることです。C#でパケットを転送中に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フォームを使用しています。
EDIT:私の以前のテストに
、上記のは本当であるように見える、それが実際にある程度のかもしれません。しかし、もう少しテストした後、私は問題が全体でInvoke(new MethodInvoker(() => { ... }));
ものであることに気づいた。それを取り除くと(UIはもちろん更新されません)、EVENTHANDLER_UpdateTransferProgress
のままにしておきますが、イベントを引き上げると、パケットの受信がはるかに高速になります。
私はイベントハンドラでInvoke()
を呼び出さずに平均約1.5秒かかったファイルを受け取ったことをテストしました。私がイベントハンドラでInvoke()
を呼び出すと、UI内のコントロールを更新したり、何らかの操作をしなくても(換言すれば、匿名メソッド本体は空だった)、約5.5秒ほどの時間がかかりました。あなたはそれが大きな違いだと分かります。
これを改善する方法はありますか?
使用している.NETのバージョンは何ですか? –
@SeanThomanこの特定のアプリケーションでは、.NET 2.0。 –
このスレッドを見る - http://stackoverflow.com/questions/661561/how-to-update-gui-from-another-thread-in-c –