電子書籍の厳選無料作品が豊富!

メインフォームの「処理開始ボタン」をクリックすると別スレッドが起動して、そのスレッド中で重たい処理をさせ、処理中に「中断ボタン」をクリックすると中断してアイドル状態に戻る様なプログラムについてですが、
先ず、Invokeを使わずに直接スレッドを起動すると期待通りの動作となり、Thread.Sleep()中でもボタンクリックのイベントが発生します。

しかし、Invokeとデリゲートを使ったスレッドを起動させるとスレッドの処理が終了するまでイベントが発生せず、行ったきり状態になってしまいます。

処理ループ内にAplication.DoEvent()を入れるとイベントが発生する様になりますが、Thread.Sleep()中はフリーズ状態となります。

Invokeを使ったスレッドでも、Invokeを使わない場合と同じ動作をさせる方法があれば教えて頂けないでしょうか。

どうぞ宜しくお願いします。

A 回答 (3件)

> やりたいことは、コントロールにアクセスする重い処理を別スレッドにさせて、必要に応じて処理を即時中断したいだけなんですけど…。



基本的にはBackgroundWorkerで可能です。
即時中断は無理で,スレッド側でキャンセルを随時調べることになります。
こうしないと,終了してはいけないところで終了する可能性があるためです。


> BackgroundWorkerを試したのですが、こちらは直接スレッドを起動した時と同様にコントロールにアクセスできない様ですし…。

ReportProgressとProgressChangedイベントを使ってください。
・DoWorkイベントはワーカースレッド上で実行されます。
・ProgressChangedイベントとRunWorkerCompletedイベントはUIスレッド上で実行されます。
どちらのスレッドで発生するかを気にしてコードを書く必要があります。


> BeginInvokeも試してみましたがInvoke同様、イベントは発生しませんでした。
> 何か使い方が間違っているのでしょうか??

デリゲート自体のBeginInvokeを利用しましたか。
ControlのBeginInvokeはワーカースレッド側をブロックせずにデリゲートをUIスレッド上で実行するための機構です。
    • good
    • 0
この回答へのお礼

いろいろと詳しい説明をして頂き、有り難うございます。

初めてのコマンドばかりですのでちょっとハードルが高そうですが、BackgroundWorkerでやってみます。

追伸、
ちょっと前にこれに関連の新質問を投稿したのですが、今後のためにこちらも回答頂けると嬉しいです。

お礼日時:2012/03/10 17:48

えーっと,Invokeというのは,


・DelegateのInvoke (C#から直接呼び出し不可,()演算子でコンパイラが読み替える)
・ControlのInvoke
のどちらでしょうか。

まず,DelegateのInvokeはそのスレッド上でデリゲートを実行します。
このため,イベントハンドラ上でDelegate.Invokeを呼び出した場合,UIスレッドをブロックします。

次に,ControlのInvokeはそのデリゲートをUIスレッド上で動かすための仕組みです。
この時,他のスレッドから呼び出した場合はデリゲートの実行が終わるまで呼び出し元のスレッドの実行をブロックします。
UIスレッドから呼び出した場合は,単純にDelegateを実行します。
また,デリゲートは実行中UIスレッドを専有します。

このため,どちらであってもデリゲートの終了までUIスレッド上でUIのイベントは原則発生しません。
デリゲートを別スレッドで実行するには,BeginInvokeを使います。
#1の方の書かれたBackgroundWorkerの方が,簡単ではありますが。
# 多段呼び出ししないようにだけ注意が必要。
    • good
    • 0
この回答へのお礼

回答、有り難うございました。

C#って本当に深いですねぇ。
デリゲートとかInvokeとか、見よう見まねで使っているだけですので内容については正直、理解できていないです。

やりたいことは、コントロールにアクセスする重い処理を別スレッドにさせて、必要に応じて処理を即時中断したいだけなんですけど…。

BackgroundWorkerを試したのですが、こちらは直接スレッドを起動した時と同様にコントロールにアクセスできない様ですし…。

BeginInvokeも試してみましたがInvoke同様、イベントは発生しませんでした。
何か使い方が間違っているのでしょうか??

お礼日時:2012/03/10 11:10

そういう時にはInvokeじゃなくてBackGroundWorkerを使うもんじゃないかと。


http://msdn.microsoft.com/ja-jp/library/system.c …
    • good
    • 0
この回答へのお礼

早速の回答、有り難うございます。

BackGroundWorkerですか…。 使ったことのないクラスなのでこれから調べてみます。

お礼日時:2012/03/09 17:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!