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

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

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

Re[2]: VB.NET マルチスレッドでDoEvents


(過去ログ 108 を表示中)

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

■64270 / inTopicNo.1)  VB.NET マルチスレッドでDoEvents
  
□投稿者/ ふぁぶ (1回)-(2012/11/20(Tue) 14:15:15)

分類:[VB.NET/VB2005 以降] 

2012/11/20(Tue) 14:28:34 編集(投稿者)
2012/11/20(Tue) 14:27:22 編集(投稿者)
2012/11/20(Tue) 14:27:12 編集(投稿者)
2012/11/20(Tue) 14:27:09 編集(投稿者)

Excel出力等、重たい処理を流している間、VBの画面が「応答なし」になります。(XP以前)(Win7では再現しません)

それを回避するために、マルチスレッドを使って、別スレッドで5000msecごとにdoeventsを実行しています。
がしかし、「応答なし」は回避できませんでした。
別スレッドでのdoeventsは意味ないのでしょうか?

Excel出力部やバッチ処理等重たい処理が複数あり、
個別でDoeventsをいれることは避けたいのです。
1つの関数をコールすることで、別スレッドをたてて、
その中で、一定周期でdoeventsを実行すればいいかと
軽く考えていたのですが。。


何か良い対策をご存知の方がいらっしゃいましたら
ご教授ください

よろしくお願いします
引用返信 編集キー/
■64271 / inTopicNo.2)  Re[1]: VB.NET マルチスレッドでDoEvents
□投稿者/ サイクロン (1回)-(2012/11/20(Tue) 14:34:11)
依然として、UIのある本スレッドで重い処理を行っているのでしょうか?
もしそうであれば、別スレッドでDoEventを行うことは、全く意味がないと思うのですが、DoEventが具体的に何をしているのかを理解する必要があると思います。
そもそも、別スレッドで重い処理を行うことが本来の姿であると思いますが、そのような設計にはしていないのでしょうか?
引用返信 編集キー/
■64272 / inTopicNo.3)  Re[2]: VB.NET マルチスレッドでDoEvents
□投稿者/ ふぁぶ (3回)-(2012/11/20(Tue) 14:54:09)
そうですね。UIのあるスレッドで重たい処理を行なっております。
というか、スレッドを分けて処理している箇所はいつもありませんでした。
(一応クラス分けはされているのですが)

工数があれば、全てを別スレッドで行えばいいというのは分かってはいるのですが、
一箇所の記述でウマイ方法があればと思い質問させて頂きました。

重たい処理を行う前に画面にマスク処理(一つのクラスで)を掛けており、そこで何かウマイ方法がないかと思案しております。

ちなみにDoeventsを少し調べはしたのですが、スレッド間でどのような違いがあるのかわかりませんでした。
よろしければ、具体的に何をしているのか教えてください。
引用返信 編集キー/
■64273 / inTopicNo.4)  Re[3]: VB.NET マルチスレッドでDoEvents
□投稿者/ ズザー (1回)-(2012/11/20(Tue) 15:04:52)
2012/11/20(Tue) 15:07:53 編集(投稿者)

> ちなみにDoeventsを少し調べはしたのですが、スレッド間でどのような違いがあるのかわかりませんでした。

「Doevents スレッド」で検索すれば、例えば以下の記事がヒットしますので確認ください。
(C#の古い記事ですが、十分参考になると思います。)

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?forum=7&topic=25267
引用返信 編集キー/
■64274 / inTopicNo.5)  Re[1]: VB.NET マルチスレッドでDoEvents
□投稿者/ ヴァン (16回)-(2012/11/20(Tue) 15:17:23)
こんにちは。

> それを回避するために、マルチスレッドを使って、別スレッドで5000msecごとにdoeventsを実行しています。

別スレッドで行っている処理はこれだけですか?
であれば、

> 別スレッドでのdoeventsは意味ないのでしょうか?

意味なしですね。

エクセルの重たい処理を BackgroundWorker などで行うことを考えた方が良いと思います。

引用返信 編集キー/
■64275 / inTopicNo.6)  Re[2]: VB.NET マルチスレッドでDoEvents
□投稿者/ howling (84回)-(2012/11/20(Tue) 16:41:38)
んー…DoEvents自体に意味はなくなってしまっているけれども、
質問者さんとしてはどうなのかなぁ…。

ズザーさんが書いてくださったURLじゃないけど、
ただ単に応答なしだけ回避したいといった程度の事が主旨なのか、
仕事だからしっかりやりたいのか謎。

ただ単に回避するだけなら、その別スレッドではなく、Excelの処理中にDoEventsを呼べばいいんじゃないのかなーと。
というか、この場合はそもそもスレッドを分ける必要が無い場合だけど。
極端な話、「Excelにデータを書き出しています」とか表示して、
たまにDoEventsで返してやるだけでどうにかなるにはなるわけだから。
仕事としてやるなら、これは当然オススメできないですが。
自分しか使わないツールとか程度なら全然いいかも。

本格的にやるならサイクロンさんの書いている通り、重い処理は別スレッドで、
メインスレッドはできるだけ軽くグルグル回すのが設計として正しいのかなと。
やるのも、うちではDoEventsで更新しているけれども、
ヴァンさんの書いているBackgroundWorkerの方がよく使われているあたり、問題が起こりにくいかなと。

いずれにしてもマルチスレッドになると、やっぱり問題発生率は上がる認識でいます。
個人でちょこっとやる程度で、重くてもいいやーって物なら別にそのままの方向でいいんじゃね?という。
頭の片隅には入れておいて欲しいですが。
引用返信 編集キー/
■64276 / inTopicNo.7)  Re[2]: VB.NET マルチスレッドでDoEvents
□投稿者/ ふるふる (2回)-(2012/11/20(Tue) 16:46:09)
もしかすると、
>Excel出力等、重たい処理
自体を見直したほうがいいかも。わざわざスレッドにしなくても、エクセルの中にマクロを用意しておいて
VBからはエクセルのマクロを呼び出すだけにするとか。
エクセルの編集では配列を使って高速化するなどテクニックがありますので、
そういった方面での見直しが効果的かもしれません。


No64274 (ヴァン さん) に返信
> こんにちは。
>
>>それを回避するために、マルチスレッドを使って、別スレッドで5000msecごとにdoeventsを実行しています。
>
> 別スレッドで行っている処理はこれだけですか?
> であれば、
>
>>別スレッドでのdoeventsは意味ないのでしょうか?
>
> 意味なしですね。
>
> エクセルの重たい処理を BackgroundWorker などで行うことを考えた方が良いと思います。
>
引用返信 編集キー/
■64278 / inTopicNo.8)  Re[1]: VB.NET マルチスレッドでDoEvents
□投稿者/ Azulean (70回)-(2012/11/21(Wed) 00:12:43)
2012/11/21(Wed) 00:17:41 編集(投稿者)

No64270 (ふぁぶ さん) に返信
> Excel出力等、重たい処理を流している間、VBの画面が「応答なし」になります。(XP以前)(Win7では再現しません)
>
> それを回避するために、マルチスレッドを使って、別スレッドで5000msecごとにdoeventsを実行しています。
> がしかし、「応答なし」は回避できませんでした。
> 別スレッドでのdoeventsは意味ないのでしょうか?

意味はありません。
「応答なし」と表示されるのは、おおざっぱに言うと、メインスレッドがメッセージループを回さないからです。
たとえば、ボタンのクリックイベントの中でずっと重たい処理を実行していると、「応答なし」になります。この場合、ボタンのクリックイベントから速やかに抜けないといけません。

よくある話としてはボタンのクリックイベントではバックグラウンドスレッドの開始とモーダルダイアログの表示だけをするというパターンです。
バックグラウンドスレッドで忙しい処理をしておき、その間に画面を触られないようにモーダル表示でガードする形です。

> Excel出力部やバッチ処理等重たい処理が複数あり、
> 個別でDoeventsをいれることは避けたいのです。
> 1つの関数をコールすることで、別スレッドをたてて、
> その中で、一定周期でdoeventsを実行すればいいかと
> 軽く考えていたのですが。。

いろいろと戦略を練り直した方が良さそうですね。
仮に、出力部やバッチ処理の合間に DoEvents を入れたとしても、そのときにボタンを押せてしまいます。
DoEvents とはそういうものなので、「入れればいい」みたいに安直に考えないでください。

// BackgroundWorker は MTA だけど、Excel オブジェクトってどうだっけ…。
引用返信 編集キー/
■64279 / inTopicNo.9)  Re[3]: VB.NET マルチスレッドでDoEvents
□投稿者/ ヴァン (17回)-(2012/11/21(Wed) 09:46:57)
こんにちは。

> エクセルの編集では配列を使って高速化するなどテクニックがありますので、

エクセルファイルを読み込む際にこれは結構有効ですね。
1セルごとに1行分読むよりは、1行丸ごとの方が高速になります。

あとはエクセル出力をCSV形式やXML形式にしちゃうとか...

引用返信 編集キー/
■64280 / inTopicNo.10)  Re[4]: VB.NET マルチスレッドでDoEvents
□投稿者/ ふるふる (3回)-(2012/11/21(Wed) 11:38:03)
Excelへの出力でも効果的ですよ。
2元配列で一気に出力すればあっという間です。
2元配列の編集に時間がかかるかもしれませんが。


No64279 (ヴァン さん) に返信
> こんにちは。
>
>>エクセルの編集では配列を使って高速化するなどテクニックがありますので、
>
> エクセルファイルを読み込む際にこれは結構有効ですね。
> 1セルごとに1行分読むよりは、1行丸ごとの方が高速になります。
>
> あとはエクセル出力をCSV形式やXML形式にしちゃうとか...
>
引用返信 編集キー/
■64315 / inTopicNo.11)  Re[2]: VB.NET マルチスレッドでDoEvents
□投稿者/ ふぁぶ (4回)-(2012/11/23(Fri) 13:15:23)
みなさま、ご回答ありがとうございます。

一応、解決しました。
解決方法は、結局、重たい処理をBackgroundWorkerでおこなうようにしました。
共通部にひとつ関数を用意して、クラス名、メソッド名、メソッドのパラメータを渡して、
一か所ですべてのExcel出力、バッチ処理を行うようにして、とりあえず修正量も少なく済ませました。

マルチスレッドに関してかなり勉強になりました。
ありがとうございました。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -