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

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

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

Re[29]: スレッドプール処理のキャンセルについて


(過去ログ 54 を表示中)

[トピック内 45 記事 (1 - 20 表示)]  << 0 | 1 | 2 >>

■30211 / inTopicNo.1)  スレッドプール処理のキャンセルについて
  
□投稿者/ らんぺるーる (39回)-(2008/12/19(Fri) 10:38:17)

分類:[.NET 全般] 

クライアント向けのソフトを開発しており、印刷準備(印刷自体ではなく印刷前の設定処理)に非常に時間が掛かるので、
そこの処理をスレッドにて作成しています。また、印刷は1つ前の処理が完了していない場合でも、キューにためておきたいので、
プール処理を考えています。

そこで、スレッド処理による印刷準備中にソフトが閉じられた場合の考慮が必要となってきました。
プール処理はバックグラウンド処理ですので、キューにためておいた処理はアプリケーションを終了しただけで、
消滅すると思いますので、問題はありません。

ただし、実行中のスレッドについては、きちんと印刷準備のキャンセル処理をおこなう必要があります。
(実際には、中途半端な状態で印刷をおこないたくないので、印刷要求を出したものを全てキャンセルします。)

ThreadクラスのStartメソッドを使用する方法で強制キャンセルの方法は、色々なHPに乗っていたのですが、
プールを使用した場合のキャンセルの方法がわかりません。

どなたか方法か、または分かりやすいHP等ご存知であれば教えていただけないでしょうか。
引用返信 編集キー/
■30218 / inTopicNo.2)  Re[1]: スレッドプール処理のキャンセルについて
□投稿者/ やじゅ (876回)-(2008/12/19(Fri) 11:11:22)
やじゅ さんの Web サイト
2008/12/19(Fri) 12:10:11 編集(投稿者)

No30211 (らんぺるーる さん) に返信
> ただし、実行中のスレッドについては、きちんと印刷準備のキャンセル処理をおこなう必要があります。
> (実際には、中途半端な状態で印刷をおこないたくないので、印刷要求を出したものを全てキャンセルします。)
>

例外で処理するとか、各スレッド全体の完了させてしまうとか
追記:一応、各スレッドを終了(中断)処理させて終わらせるのがいいかと

スレッド内で発生した例外 まとめ
http://blog.livedoor.jp/gushwell/archives/2007-06.html

ThreadPoolに溜まっている各スレッド全体の完了
http://bbs.wankuma.com/index.cgi?mode=al2&namber=26896&KLOG=49

引用返信 編集キー/
■30225 / inTopicNo.3)  Re[2]: スレッドプール処理のキャンセルについて
□投稿者/ なちゃ (231回)-(2008/12/19(Fri) 11:45:28)
基本的にはキャンセル要求を監視してスレッド側で終了またはキャンセル処理をするしかないでしょう。
デリゲートをインスタンスメソッドにしとけば、キャンセル要求なども管理出来ます。

AsyncOperationだったか辺り使えば組み込みのキャンセル要求なども使えたかも。
引用返信 編集キー/
■30229 / inTopicNo.4)  Re[3]: スレッドプール処理のキャンセルについて
□投稿者/ 渋木宏明(ひどり) (994回)-(2008/12/19(Fri) 11:55:35)
渋木宏明(ひどり) さんの Web サイト
> 基本的にはキャンセル要求を監視してスレッド側で終了またはキャンセル処理をするしかないでしょう。

です。

現状でも終了待ち合わせの処理があるはず(無いとしたらちょと手抜き)なので、各スレッドに自発的に終了(中断)を促すのが正道です。

例外なんか下手に使うと、スレッド内で使用しているアンマネージリソースの廃棄が適切に行われない場合もあったりするので、お勧めしません。

引用返信 編集キー/
■30260 / inTopicNo.5)  Re[4]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (40回)-(2008/12/19(Fri) 16:43:18)
なるほど!メイン処理から強制的にスレッドを終了させることしか考えていませんでしたが、
スレッド側から、メイン処理の終了を監視しておき、メイン処理が終了を通知したら、スレッド側も
終了処理をおこなえばいいということですか…。

メイン側は、スレッド側の終了処理を待ってから、最後に終了する必要がありそうですね…。
引用返信 編集キー/
■30265 / inTopicNo.6)  Re[5]: スレッドプール処理のキャンセルについて
□投稿者/ やじゅ (877回)-(2008/12/19(Fri) 17:23:32)
やじゅ さんの Web サイト
No30260 (らんぺるーる さん) に返信
> スレッド側から、メイン処理の終了を監視しておき、メイン処理が終了を通知したら、スレッド側も
> 終了処理をおこなえばいいということですか…。
>

なんか違う・・・、スレッド側からメイン処理の終了を監視しなくてもいいよ。
各スレッドに、もうこれで終わりだよって指令だして、各スレッドが徐々に終了していく仕組みを作る
引用返信 編集キー/
■30270 / inTopicNo.7)  Re[6]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (43回)-(2008/12/19(Fri) 18:43:28)
返答ありがとうございます。

手順としては以下のような感じであっているでしょうか。
@スレッドプールで印刷処理を実行。
A印刷処理中にフォームを閉じる。
B「FormClosing」イベントで、実行中のスレッドがあるか確認する。
C実行中のスレッドがある場合は、
 「FormClosing」イベントにて実行中のスレッドにたいして
  終了処理を依頼する。(処理が終了するまでメイン処理はWaitする。
D実行中のスレッドにてスプール中の印刷をキャンセルする。
Eスレッドの終了をメイン処理に報告する。
Fメイン処理を終了する。

ここで、今実現方法がわからないのが
CDEです。
インターネットで調べてはいるのですが、
スレッドプールで実行中のスレッドに対して、
キャンセルの依頼は出せるのでしょうか…。

特にDの処理はむずかしく、現在実行中の印刷処理を途中でやめて
印刷キャンセル処理に切り替えをする必要があるということですよね。





引用返信 編集キー/
■30275 / inTopicNo.8)  Re[7]: スレッドプール処理のキャンセルについて
□投稿者/ まどか (595回)-(2008/12/19(Fri) 21:21:05)
No30270 (らんぺるーる さん) に返信
> スレッドプールで実行中のスレッドに対して、
> キャンセルの依頼は出せるのでしょうか…。

スレッドだろうとスレッドプールであろうと、実行中のメソッド内でキャンセル要求を感知できればよいわけです。

スレッド処理メソッドを含むクラスを作って
Start(), Stop(), Cancel() などを実装するのがよくあるパターンでしょうか。
起動する側はそのインスタンスの参照を覚えておけばキャンセル要求できますよね。
あとイベントを実装れば起動側で進捗表示もできます。

まぁ、起動と処理が同じクラス(フォームなど)であっても、単にキャンセル用Private変数をTrueにして処理内で監視するだけです。
引用返信 編集キー/
■30307 / inTopicNo.9)  Re[8]: スレッドプール処理のキャンセルについて
□投稿者/ やじゅ (882回)-(2008/12/20(Sat) 19:55:32)
やじゅ さんの Web サイト
> ■No30270 (らんぺるーる さん) に返信
>>スレッドプールで実行中のスレッドに対して、
>>キャンセルの依頼は出せるのでしょうか…。
>

スレッド化による方法 If canceled Then として、スレッド内でループを抜けている
http://dobon.net/vb/dotnet/programing/abortprocess.html

スレッドプールであっても、その中のスレッドにて中断フラグを使って
それ以降の処理(スレッド含めて)をすぐに終わらせればいいと思うわけです。
引用返信 編集キー/
■30359 / inTopicNo.10)  Re[9]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (44回)-(2008/12/22(Mon) 13:49:52)
ご回答有難うございました。
スレッドのクラスにキャンセル用の変数を設けて、メイン処理側からフラグを立てることで、
印刷キャンセルが出来ました。

ただし、1点解決できない点があります。
スレッドのキャンセルが終わるまで、メイン処理はWaitしなくてはいけないので、
スレッドの処理が終わったかどうかのフラグをスレッドクラスに用意しました。

スレッドのキャンセル処理が終わったらフラグを立てるように実装しています。
メイン処理の「FormClosing」イベントで、スレッドクラスのフラグが立つまで
「System.Threading.Thread.Sleep(1000)」を繰り返し、
キャンセル処理が終わるのを待つようにしたいのですが、
いつまでたってもキャンセルフラグが立ちません。
完全にはマルチ処理になっていないように見えます。

どのように対処すればよいか教えていただけないでしょうか。
引用返信 編集キー/
■30365 / inTopicNo.11)  Re[10]: スレッドプール処理のキャンセルについて
□投稿者/ なちゃ (232回)-(2008/12/22(Mon) 14:20:03)
簡単な方法としては、対象スレッド全部でJoinしたらいいだけな気もする。

プラグやらチェックやらどうやってるのか分からないので、なぜ終わらないかは何とも言えません。
可能性は色々と…


引用返信 編集キー/
■30367 / inTopicNo.12)  Re[11]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (45回)-(2008/12/22(Mon) 14:45:04)
スレッドクラスに現在実行中の印刷処理のスレッドを「System.Threading.Thread.CurrentThread」
で保持しておき、メインメソッドより「Join」を発行すれば、処理がスレッドクラスにうつり、
無事印刷キャンセルをおこなえました!!

また、問題が…。
スレッド処理が「End Sub」までいって、完了しているのにもかかわらず、
メイン処理が「Join」でとまってしまいます…。

あともうちょっとなんですがっ。
助言いただけないでしょうか。

引用返信 編集キー/
■30369 / inTopicNo.13)  Re[12]: スレッドプール処理のキャンセルについて
□投稿者/ なちゃ (233回)-(2008/12/22(Mon) 14:52:46)
あ、ごめんなさい、スレッドプールでしたね…
これはメソッド抜けても終わらないので、Joinじゃ駄目ですね…

プラグ管理でもきちんと作ればちゃんと終わるはずですが…

あとは最初の方でやじゅさんがリンクしてた、スレッド完了待ちの辺りを参考にしてもいいですが…

引用返信 編集キー/
■30372 / inTopicNo.14)  Re[13]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (46回)-(2008/12/22(Mon) 15:07:40)
あ!スレッドプールですが、メイン処理で「Join」を発行するのは、
現在実行中のスレッドにたいしてです。

スレッドクラスに以下の変数をもうけました。
Public t As System.Threading.Thread 'スレッド

スレッドで実行するメソッドを用意してその中でメンバの
スレッド用変数に格納しました。

Private Sub BatchPrintRun(stateInfo As Object)
 t = System.Threading.Thread.CurrentThread
End Sub

そして、メインメソッドより「t.join」を実行したのですが、
かえってきませんでした…。


引用返信 編集キー/
■30375 / inTopicNo.15)  Re[14]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (47回)-(2008/12/22(Mon) 15:36:48)
プールではなく、通常のスレッド処理にすればうまくいきました。
なちゃさんがおっしゃる通り、スレッドプールで実行したスレッドに
対しては「Join」が使用できないようです。

スレッドプールで実行したスレッドに処理を渡し、完了を待つには
どうすればいいのでしょうか…。

メイン画面の「FormClosing」イベントをキャンセルすれば
またスレッド処理が動きだすんですけど、
「FormClosing」イベントの中で、スレッドに処理を渡すことは
できないのでしょうか。

引用返信 編集キー/
■30380 / inTopicNo.16)  Re[15]: スレッドプール処理のキャンセルについて
□投稿者/ やじゅ (884回)-(2008/12/22(Mon) 16:19:15)
やじゅ さんの Web サイト
No30375 (らんぺるーる さん) に返信

いまいち、らんぺるーる さんが何で(この何では素直にやればいいのにの意味)悩んでいるかが分からないですね。

ThreadPoolに溜まっている各スレッド全体の完了
http://bbs.wankuma.com/index.cgi?mode=al2&namber=26896&KLOG=49

上記のリンク先の片桐さん案とか、なちゃさんの案で試してみてはどうですか?

クラスのStatic変数として2つ準備
A:実行JOB数をカウントするLong型
B:実行済JOB数をカウントするLong型
呼び出し元でThreadPoolへQueueするタイミングに、Aをインクリメント
ThreadPoolから呼び出されるスレッドの終了時に、Bをインクリメント
呼び出し元はA<=BとなるまでSleepで待機
引用返信 編集キー/
■30383 / inTopicNo.17)  Re[16]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (48回)-(2008/12/22(Mon) 16:54:45)
>やじゅさん
今回おこないたい仕様の前提について、記載します。

スレッドプールにたまっている全部のスレッドが完了するまで、
アプリケーションを閉じられなくするのではなく、
「印刷途中ですが、アプリケーションをとじますか?」のような
メッセージを出力し、ユーザに選択させたかったのです。
(今回の印刷処理は非常に時間掛かるので、全ての印刷が終わるまで
アプリケーションを終了できないのは、まずいという意見がありました。)

「はい」が選択されて、スレッドの印刷処理中に閉じられた場合に、実行中のスレッドを
を中止し、プリンタへの印刷要求をキャンセルする場合の問い合わせでした。
引用返信 編集キー/
■30389 / inTopicNo.18)  Re[17]: スレッドプール処理のキャンセルについて
□投稿者/ やじゅ (885回)-(2008/12/22(Mon) 18:34:07)
やじゅ さんの Web サイト
2008/12/22(Mon) 18:36:03 編集(投稿者)

No30383 (らんぺるーる さん) に返信
> スレッドプールにたまっている全部のスレッドが完了するまで、
> アプリケーションを閉じられなくするのではなく、
> 「印刷途中ですが、アプリケーションをとじますか?」のような
> メッセージを出力し、ユーザに選択させたかったのです。

それは分かります、なので例えキャンセルを途中でしたとしても、
最後までスレッドプールにたまっている処理を行うようにするのです。

スレッドプールは中断することが出来ないので、キャンセル後は
スレッドプールにたまっている処理を、空処理(ダミー)して終わら
せるのです。

この考えが私とは一致しないようですね。
引用返信 編集キー/
■30390 / inTopicNo.19)  Re[18]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (49回)-(2008/12/22(Mon) 19:45:29)
やじゅさんのおっしゃる処理で全然OKです。

「FormClosing」イベントからstaticなメンバ等に
キャンセルフラグを立ててあげて、
そのキャンセルフラグが立っている場合は、
スレッド処理ではなにもしないで終了で構いません。

今うまくいっていないのは、「FormClosing」イベント
でスレッドの総数と、実行済みスレッド数の比較をし、
一致するまでメイン処理がWaitするというところです。
(リンクを張っていただいた片桐さんとほぼ同じ処理を
いれました)

「FormClosing」イベントに以下のように記載し、
スレッド処理が終わるのをWaitしているのですが、
スレッド側が動いていないように思います。

そこで先ほどは、「Join」メソッドを発行してみたのですが、
プール処理ではうまく結果がかえってきませんでした。

Do Until poolCount_start = poolCount_end
System.Threading.Thread.Sleep(1000)
Loop

引用返信 編集キー/
■30398 / inTopicNo.20)  Re[14]: スレッドプール処理のキャンセルについて
 
□投稿者/ Azulean (253回)-(2008/12/22(Mon) 22:09:41)
2008/12/22(Mon) 22:10:35 編集(投稿者)

> Do Until poolCount_start = poolCount_end
> System.Threading.Thread.Sleep(1000)
> Loop
このコードはメインスレッドを止めつつ様子を見るコードになります。
スレッドプールに預けた処理がメインスレッドに対してウィンドウメッセージを投げたり、Invokeするようなコードを持っている場合、デッドロック状態になるんじゃないかな。
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 | 2 >>

管理者用

- Child Tree -