• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:c#のメソッドjoinが機能しない)

C#のメソッドjoinが機能しない

このQ&Aのポイント
  • C#のメソッドjoinが意図した動作を行わない問題について質問です。
  • 質問者はMicrosoft Visual C# 2005でスレッドを使用したプログラムを行なっています。
  • 質問者はフォルダから連番の画像を読み込んでは表示する動作を実装していますが、スレッドの終了を待つ処理が上手く機能していないようです。また、画像の再生時間にも誤差があるとのことです。具体的なアドバイスを求めています。

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.1

>A表示のスレッドのjoinを待つ前にB表示のスレッドが始まってしまっているようです. >Read.Start(); >if(now_loading == true) この間にスレッド切り替えが発生して、read_image()のnow_loading = trueが処理される。 という保証は無いかと思いますが、どうなんでしょうかね? Thread.Sleep()でスレッド切り替えの機会を入れれば…というのはありますが、それでも確実ではないでしょう。 # 何より、イベントハンドラ内でそういう待ちは入れるべきではない…かと。 now_loadingとかnow_showingとかはスレッドセーフなオブジェクトなんですか? >if(now_loading == true) で判定した直後にスレッド切り替えが発生してnow_loadingの値が変わる…とかいうことはないのでしょうか? # 該当処理中に「now_loading」が変化しないから最適化で実効コードが消える。 # なんてことはC#であるんでしょうかね?

Meimei88
質問者

お礼

回答ありがとうございます. 【訂正】 フォルダ1の前の if(now_showing == true) { Reads.Join(); } のnow_showingはnow_loadingの間違いです.失礼しました. >>Read.Start(); >>if(now_loading == true) >この間にスレッド切り替えが発生して、read_image()のnow_loading = trueが処理される。 >という保証は無いかと思いますが、どうなんでしょうかね? ご指摘頂いたとおり,確認してみたところ先にif文の方が判定される場合があり,その時にスレッドが終了していないままjoinもスルーされていたようです. 単純にif(now_loading == true)の下りを削除し,joinは必ず実行されるようにしたところ,出力でチェックする限りは最初のフォルダの再生終了前にBが再生され始めるということは無くなりました. また,再生時間も実測時間と同じになりました. ただ,Reads.Join();の部分でInbaridOperationExeceptionはハンドルされませんでしたとエラーが出たのですが,対象とするスレッドが終了しているのが理由と見てもいいのでしょうか.joinは対象とするスレッドが終了している場合,特に何もエラーは出ないと考えていたのですが. この部分のみ,if(now_loading==true)で囲んでみたりもしたのですが,読込スレッド内のnow_loadingのtrue(もしくはfalse)切り替えとかぶってしまうのか,同様のエラーが出ました. また,読み込みが終わってから表示を始めているのですが,一つ目のフォルダ再生の際にどうしてもカクカクとした動きになってしまうのですが,メモリを見る限り不足している様子はないのですが,解決策はあるのでしょうか…. joinが何故スルーされるか分からなかったので,原因が分かって良かったです.有難うございます. now_loadingをスレッドセーフにすれば良いのかとdalegate型を使おうと一から調べているのですが,理解が遅くもう少し掛かりそうです. お気づきのところがあれば,引き続きご指摘頂けると嬉しいです.

その他の回答 (1)

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.2

C#自体たいして経験があるワケではないのですが… # しかも使っているのは.NET Framework 4の方。 # 自宅PCにインストールしてあるVS2005StdのC#は使っていないし…。 >ただ,Reads.Join();の部分でInbaridOperationExeceptionはハンドルされませんでしたとエラーが出たのですが,対象とするスレッドが終了しているのが理由と見てもいいのでしょうか. たぶん、別…ではないですかね。 スレッド内の処理のどれかが例外出しているんじゃないかと思われますが……。 >joinは対象とするスレッドが終了している場合,特に何もエラーは出ないと考えていたのですが. ヘルプだとそう書かれてますね。 タイミングなんですかねぇ……。 ところでInbaridOperationExeceptionの例外にはどんなメッセージついていましたか?

Meimei88
質問者

お礼

>>ところでInbaridOperationExeceptionの例外にはどんなメッセージついていましたか? 試しに,if(now_loading==true)の下りを全て削除し,呼び出すスレッドの名前を全て統一してみたところ,InvaridOperationExeceptionは出なくなりました.以降そのまま進めているのでメッセージは確認できませんでした.ただ,10回程度回しただけなので運が良かっただけかもしれません…. Joinメソッドは対象とするスレッドが終了している場合は問題ないようですが,ThreadState.Unstarted 状態のスレッドで Join を呼び出すことはできないようなのでそれが原因かもと思っています. 表示が想定どおりに行かないので,Thread.Abortを取り入れたところ一つ目のフォルダは問題なく表示されるようになったのですが,やはり二つ目が想定表示時間よりも短くなるようです. Joinの挙動についてはおかげで解決しましたので,Abortは新たに質問し直させて頂きました.一旦この質問版は閉じさせて頂きます. 回答有難うございました.

関連するQ&A