C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: マルチスレッドでフォアグランド処理の方が重い場合


(過去ログ 138 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■81057 / inTopicNo.1)  マルチスレッドでフォアグランド処理の方が重い場合
  
□投稿者/ JOJO (1回)-(2016/08/26(Fri) 22:13:24)

分類:[.NET 全般] 


VBをつかってマルチスレッド処理のプログラムを作成しました。


MultiProgram_run = New System.Threading.Thread( _
New System.Threading.ParameterizedThreadStart(AddressOf Program_runxx))

MultiProgram_run.IsBackground = True

MultiProgram_run.Start()

のようにして、バックグランドで数値計算を行い、
計算結果を配列に格納し、
BeginInvokeでフォアグラウンド処理に回し、
その配列の結果をChart表示するというものです。

データ点数が少ない時には問題ないのですが
データ点数が1万点を超えると、Chartへの反映に時間がかかる(処理が重くなる)ため、
マルチスレッド処理をしているにも拘わらず、
フォームがフリーズしてしまうという現象が起きます。

一つの解決策としては、
バックグランド処理の中で
Forループの中の
BeginInvokeの頻度を下げるというものです。

もし数値計算処理にかかる時間が毎回同じであれば
これでも問題ないのですが
パラメータを変えると数値計算にかかる時間がかかるため、
BeginInvokeの頻度が多すぎたり、逆に少なすぎたりしてしまいます。

そのため、フォアグラウンド処理の中で画面更新のために
一休止を入れるようなことをしたいのですが
どうすれば良いでしょうか?

まず思いついたのは、Thread.Sleep(1)を入れてみました。
しかしフォアグランド処理が休んでいても画面更新は行われません。

次に、Application.DoEventsを入れてみました。
しかしこれでもフリーズしてしまいます。

一体、どうするのが良いでしょうか?

引用返信 編集キー/
■81058 / inTopicNo.2)  Re[1]: マルチスレッドでフォアグランド処理の方が重い場合
□投稿者/ JOJO (2回)-(2016/08/26(Fri) 22:14:50)
すいません、追記します。
BeginInvokeでフォアグラウンド処理に回し、
その配列の結果をChartに回すというのは
計算が数時間とか非常に時間がかかるため
計算が終わってからChart表示するのではなく
リアルタイムで計算結果の途中経過を表示するというものです。
 
引用返信 編集キー/
■81063 / inTopicNo.3)  Re[2]: マルチスレッドでフォアグランド処理の方が重い場合
□投稿者/ なちゃ (137回)-(2016/08/27(Sat) 20:16:20)
No81058 (JOJO さん) に返信
> すいません、追記します。
> BeginInvokeでフォアグラウンド処理に回し、
> その配列の結果をChartに回すというのは
> 計算が数時間とか非常に時間がかかるため
> 計算が終わってからChart表示するのではなく
> リアルタイムで計算結果の途中経過を表示するというものです。
>  

データ数が非常に多い場合、そもそも画面に全データは反映できないことになるのが普通ですので、描画に大きく影響が出ないようにうまく表示用データを省くとかが常套手段のような気がします。
引用返信 編集キー/
■81064 / inTopicNo.4)  Re[3]: マルチスレッドでフォアグランド処理の方が重い場合
□投稿者/ なちゃ (138回)-(2016/08/27(Sat) 20:19:56)
No81063 (なちゃ さん) に返信
> ■No81058 (JOJO さん) に返信
>>すいません、追記します。
>>BeginInvokeでフォアグラウンド処理に回し、
>>その配列の結果をChartに回すというのは
>>計算が数時間とか非常に時間がかかるため
>>計算が終わってからChart表示するのではなく
>>リアルタイムで計算結果の途中経過を表示するというものです。
>> 
>
> データ数が非常に多い場合、そもそも画面に全データは反映できないことになるのが普通ですので、描画に大きく影響が出ないようにうまく表示用データを省くとかが常套手段のような気がします。

例えば、折れ線グラフを書いたとして、一万個のデータは普通画面の横解像度を超えるので、どちらにしても全部は表現できません。
例えば画面の横解像度程度の区間でデータを区切り、その区間内での最大値と最小値をうまく使えば、実質的に表示に影響を与えずにデータを減らすことが出来ます。
とかまあそういう話です。
引用返信 編集キー/
■81066 / inTopicNo.5)  Re[4]: マルチスレッドでフォアグランド処理の方が重い場合
□投稿者/ 774RR (446回)-(2016/08/28(Sun) 06:22:42)
UI スレッドに sleep を入れるのは
「その間描画処理を一切しないし、キーボードやマウスを受け付けない」というプログラマの意思表明なので
やっちゃダメ。

DoEvents は一見使えそうだけど、使うと逆にハマるのでオイラは推奨しない。

んで本題としてはすでに回答が出ている通り「間引けばよい」んでないかな。
どっちで(計算する側のワーカースレッドでするか、描画側の UI スレッドでするか)間引くかは、は要検討

逆に考えると
・計算するワーカースレッドは計算するだけ (描画の依頼をしない)
・ UI スレッドは計算中にはタイマーで定期的に計算結果を複写して、その複写データを描画
 →描画が間に合わなかったらタイマーイベントがどんどん遅れる=画面更新が遅いだけ
でもよいかも。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -