
メインフォームの「処理開始ボタン」をクリックすると別スレッドが起動して、そのスレッド中で重たい処理をさせ、処理中に「中断ボタン」をクリックすると中断してアイドル状態に戻る様なプログラムについてですが、
先ず、Invokeを使わずに直接スレッドを起動すると期待通りの動作となり、Thread.Sleep()中でもボタンクリックのイベントが発生します。
しかし、Invokeとデリゲートを使ったスレッドを起動させるとスレッドの処理が終了するまでイベントが発生せず、行ったきり状態になってしまいます。
処理ループ内にAplication.DoEvent()を入れるとイベントが発生する様になりますが、Thread.Sleep()中はフリーズ状態となります。
Invokeを使ったスレッドでも、Invokeを使わない場合と同じ動作をさせる方法があれば教えて頂けないでしょうか。
どうぞ宜しくお願いします。
No.3ベストアンサー
- 回答日時:
> やりたいことは、コントロールにアクセスする重い処理を別スレッドにさせて、必要に応じて処理を即時中断したいだけなんですけど…。
基本的にはBackgroundWorkerで可能です。
即時中断は無理で,スレッド側でキャンセルを随時調べることになります。
こうしないと,終了してはいけないところで終了する可能性があるためです。
> BackgroundWorkerを試したのですが、こちらは直接スレッドを起動した時と同様にコントロールにアクセスできない様ですし…。
ReportProgressとProgressChangedイベントを使ってください。
・DoWorkイベントはワーカースレッド上で実行されます。
・ProgressChangedイベントとRunWorkerCompletedイベントはUIスレッド上で実行されます。
どちらのスレッドで発生するかを気にしてコードを書く必要があります。
> BeginInvokeも試してみましたがInvoke同様、イベントは発生しませんでした。
> 何か使い方が間違っているのでしょうか??
デリゲート自体のBeginInvokeを利用しましたか。
ControlのBeginInvokeはワーカースレッド側をブロックせずにデリゲートをUIスレッド上で実行するための機構です。
いろいろと詳しい説明をして頂き、有り難うございます。
初めてのコマンドばかりですのでちょっとハードルが高そうですが、BackgroundWorkerでやってみます。
追伸、
ちょっと前にこれに関連の新質問を投稿したのですが、今後のためにこちらも回答頂けると嬉しいです。
No.2
- 回答日時:
えーっと,Invokeというのは,
・DelegateのInvoke (C#から直接呼び出し不可,()演算子でコンパイラが読み替える)
・ControlのInvoke
のどちらでしょうか。
まず,DelegateのInvokeはそのスレッド上でデリゲートを実行します。
このため,イベントハンドラ上でDelegate.Invokeを呼び出した場合,UIスレッドをブロックします。
次に,ControlのInvokeはそのデリゲートをUIスレッド上で動かすための仕組みです。
この時,他のスレッドから呼び出した場合はデリゲートの実行が終わるまで呼び出し元のスレッドの実行をブロックします。
UIスレッドから呼び出した場合は,単純にDelegateを実行します。
また,デリゲートは実行中UIスレッドを専有します。
このため,どちらであってもデリゲートの終了までUIスレッド上でUIのイベントは原則発生しません。
デリゲートを別スレッドで実行するには,BeginInvokeを使います。
#1の方の書かれたBackgroundWorkerの方が,簡単ではありますが。
# 多段呼び出ししないようにだけ注意が必要。
回答、有り難うございました。
C#って本当に深いですねぇ。
デリゲートとかInvokeとか、見よう見まねで使っているだけですので内容については正直、理解できていないです。
やりたいことは、コントロールにアクセスする重い処理を別スレッドにさせて、必要に応じて処理を即時中断したいだけなんですけど…。
BackgroundWorkerを試したのですが、こちらは直接スレッドを起動した時と同様にコントロールにアクセスできない様ですし…。
BeginInvokeも試してみましたがInvoke同様、イベントは発生しませんでした。
何か使い方が間違っているのでしょうか??
No.1
- 回答日時:
早速の回答、有り難うございます。
BackGroundWorkerですか…。 使ったことのないクラスなのでこれから調べてみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- その他(学校・勉強) この中で間違ってある説明はありますか?詳しい方に教えていただきたいです。 A. 1つのプログラムが複 2 2023/07/14 01:15
- その他(パソコン・スマホ・電化製品) 先日、OPTIPLEX790を使用しスリープ機能で電源が落ちた後に電源が付かなくなるトラブルが発生し 1 2022/12/20 01:53
- Windows 8 QTTabBarが無反応になる 2 2023/04/07 14:17
- Access(アクセス) アクセス 意図せずサブプロシージャを移動してしまうのを止めたい 1 2022/09/02 09:19
- BTOパソコン PCの選び方 6 2022/09/11 00:16
- デスクトップパソコン 「自動修復でPCを修復できませんでした」と表示されPCが起動しないのですが対処法はありますか? 5 2022/05/13 09:16
- CPU・メモリ・マザーボード CPUについて 4 2022/07/09 13:41
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スレッドの監視方法について
-
PHP5のスレッドについて、
-
pthreadの使い方
-
スレッドの終了はどうやるんで...
-
Linuxでスレッド優先度って変え...
-
同一スレッドで、ロックをかけ...
-
MFC モーダルダイアログに動的...
-
メインスレッドのPostMessageと...
-
Windows上で、シグナル(SIGTERM...
-
.netアプリへのSendMessageでフ...
-
別スレッドからのフォームのテ...
-
スレッド一覧の取得
-
スレッドの名前の取得について
-
VC++スレッドの正しい終了のさ...
-
_beginthreadとPostThreadMessa...
-
自作クラスのイベントを外部ハ...
-
スレッドの安全な終了のさせ方
-
スレッドの終了の仕方
-
スレッドを効率的に使うとは?
-
マルチスレッドプログラム
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
スレッドの監視方法について
-
VC++スレッドの正しい終了のさ...
-
スレッドにて同一メモリの書き...
-
スレッドの終了の仕方
-
VB2005 シリアル通信のClose処理
-
WaitForSingleObjectの使い方に...
-
別スレッドのデータを受信できない
-
同一スレッドで、ロックをかけ...
-
CWnd::OnTimerのスレッドの取得
-
スレッドの安全な終了のさせ方
-
メインダイアログが最背面に表...
-
スレッド一覧の取得
-
Windows上で、シグナル(SIGTERM...
-
C言語で一定時間待機後、再実行
-
C#でスレッド実行中のイベント...
-
複数スレッドを動作させるのに...
-
.netアプリへのSendMessageでフ...
-
DirectX LPDIRECT3DDEVICE9のマ...
-
スレッド内でコントロールやWin...
-
DirectX 11のConsntanBuffer
おすすめ情報