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

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

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

Re[18]: 新しいスレッド上からBeginInvokeで「時々」固まる


(過去ログ 84 を表示中)

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

■49871 / inTopicNo.1)  新しいスレッド上からBeginInvokeで「時々」固まる
  
□投稿者/ たか (36回)-(2010/05/21(Fri) 10:46:28)

分類:[C#] 

2010/05/21(Fri) 10:47:43 編集(投稿者)
2010/05/21(Fri) 10:47:36 編集(投稿者)
2010/05/21(Fri) 10:47:31 編集(投稿者)

<pre><pre>こんにちは

.netframework3.5でWindowsアプリ作ってます。
WEBの自動巡回ツールのようなものを作っているのですが ごくまれに固まってしまったり
エラーがキャッチできないことがあります。
いつも発生するわけではなくごく稀になので原因がつかめず悩んでます。
原因わかりましたら教えてください。


ボタンクリックイベント{
  //新しいスレッドを作成
  threads = new Thread(new ParameterizedThreadStart(startThreadMain));
  threads.IsBackground = true;
  //スレッドで処理するqueueを引数で渡して起動
  threads.Start(thqueues); 
}

delegate void CloseDelegate();

private void startThreadMain(Object o) {
  //スレッド内での処理をするQueue
  ThreadQueue thqueue = (ThreadQueue)o;
  try {
    //メイン処理を行う
    //MainClass.Main内でWebBrowserをNEWしてWEBから情報を取得し
    //その結果をFormアプリに結果を返す
    DeleMain sbook = new DeleMain (MainClass.Main);

    //
    IAsyncResult ret = this.BeginInvoke(sbook, new object[] { thqueue });
    //登録処理が終わるまで待つ
    ret.AsyncWaitHandle.WaitOne();
    if (ret.IsCompleted) {
      //↓EndInvokeの行でNullReffrenceExceptionが稀に発生するが下でcatchできない
      object obj = this.EndInvoke(ret);
    }
    //終了時の処理    

    //終了メッセージを画面表示
    Invoke(new CloseDelegate(finish));

  } catch (Exception ex) {
    //エラー処理
  }
}


ちなみにWebアプリケーション(ASP.netとかPHP,Perl)は専門なのですが
Windowsアプリはこれが初めてで マルチスレッドの考え方が根本的に何か問題あるのかもしれません。
おかしい点があればご指摘いただければ幸いです。
よろしくお願いします。</pre></pre>

引用返信 編集キー/
■49877 / inTopicNo.2)  Re[1]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ 渋木宏明(ひどり) (1332回)-(2010/05/21(Fri) 11:40:50)
渋木宏明(ひどり) さんの Web サイト
直接の回答ではありませんが…

> //MainClass.Main内でWebBrowserをNEWしてWEBから情報を取得し
> //その結果をFormアプリに結果を返す

MainClass.Main に STAThread 属性つけてますか?

あと、これってワーカースレッドからプライマリスレッドが保持する WebBrowser に処理依頼してる、ってことですよね?

だとすると、結局同時に1つの処理しか実行できないので、マルチスレッド化する意味が無いような…

> Windowsアプリはこれが初めてで マルチスレッドの考え方が根本的に何か問題あるのかもしれません。

マルチスレッドもそうですが、WebBrowser 使って込み入ったことをしようとすると、COM や OEL の知識、.NET の COM 相互運用の知識なども必要になります。

引用返信 編集キー/
■49878 / inTopicNo.3)  Re[2]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (37回)-(2010/05/21(Fri) 11:54:13)
ありがとうございます。

> MainClass.Main に STAThread 属性つけてますか?
属性何もつけてないですね
試しにつけてみたいと思います。


> あと、これってワーカースレッドからプライマリスレッドが保持する WebBrowser に処理依頼してる、ってことですよね?
>
> だとすると、結局同時に1つの処理しか実行できないので、マルチスレッド化する意味が無いような…

ワーカースレッド内で WebBrowserをnewして そこで新規作成した表面上は見えないWebBrowser内で処理しているので
プライマリスレッドのWebBrowserを呼び出しているわけではありません。
なのでワーカースレッド終了時にDisposeしてます。

なおWebBrowserでは情報収集したいだけなので特定ページを指定した順番で遷移したりリンクをクリックしたりして
最終的に表示される情報の一部を取得して返す、といった処理です。


> マルチスレッドもそうですが、WebBrowser 使って込み入ったことをしようとすると、COM や OEL の知識、.NET の COM 相互運用の知識なども必要になります。

WebBrowserでやる処理は単純なので COM使わないと、ってな自体は今のところ発生していないです。
というか発生しない使用で使わずに済ませる方向で仕様作ってます。
COMについては何回か調べましたが まさかCookie削除するだけであんなに大変だとは思わなかったので・・・
確かに深入りするとCOMの知識とか必要なのはひしひしと感じてますが
WebBrowserの基本機能だけで実装しています。

引用返信 編集キー/
■49879 / inTopicNo.4)  Re[2]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (38回)-(2010/05/21(Fri) 11:59:46)
あと補足ですが 上のソースでは省略しましたが実際には同時に最大4つのワーカースレッド立ち上げて そのそれぞれのワーカースレッドでWebBrowserをnewして
1ワーカースレッドにつき1WebBrowserを使って情報を取得しています。

きちんとマルチスレッドとして機能していて4件同時に取得して独立してうまく動いています。
(上記のようにまれに固まったりしますが)

なお上記の現象はワーカースレッド1つの場合でも発生しているので ワーカースレッド間のデッドロックとかではなさそうです。
引用返信 編集キー/
■49880 / inTopicNo.5)  Re[3]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ なちゃ (435回)-(2010/05/21(Fri) 12:08:48)
根本的にスレッドの使い方が変です。
なぜ自分でスレッドを開始してるのに、その後わざわざ非同期実行を行って、
しかもいきなり完了まで待ってるんでしょうか?

また、非同期実行してる処理はスレッドプールで実行されますのでMTAです。
これは変えることは出来ません、STAにするには自分で作ったスレッドで明示的に設定する必要があります。

引用返信 編集キー/
■49881 / inTopicNo.6)  Re[3]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ 渋木宏明(ひどり) (1333回)-(2010/05/21(Fri) 12:39:39)
渋木宏明(ひどり) さんの Web サイト
> ワーカースレッド内で WebBrowserをnewして そこで新規作成した表面上は見えないWebBrowser内で処理しているので

であれば、ワーカースレッドを STA にする必要があります。
STAThread 属性がなんなのか、どういう効果があるのかを調べてみてください。

あと、なちゃさんも指摘してますが、どうしてワーカースレッドで非同期処理なんか実行しているんでしょう?

処理がワーカースレッドないで完結するのであれば、全く意味がありません。

ひょっとして、ワーカースレッドで逐次的に WebBrowser を操作するコードが期待通りの動作をしなくて、その対策だったりしますか?

であれば、それは正しい対処ではありません。

WebBrowser を正しく動作させるためには、メッセージループが必要です。

なので、ワーカースレッドで WebBrowser を扱うのであれば、ワーカースレッドでメッセージループを回すことになります。

が、複数のワーカースレッドで独自にメッセージループを回した状態でも WebBrowser が期待通りに動作するかどうか、僕には実績がないので分かりません。

> WebBrowserでやる処理は単純なので COM使わないと、ってな自体は今のところ発生していないです。

直接使うことはなくても、不具合が発生した際に、その現象をきちんと理解するために必要になることがあります。

WebBrowse を扱うのに、STAThread 属性やメッセージループが必要であることなどは、.NET の WebBrowser が、COM/OLE 技術を基盤として作られたブラウザコントロールのラッパであることに起因します。

引用返信 編集キー/
■49889 / inTopicNo.7)  Re[4]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (39回)-(2010/05/21(Fri) 16:03:58)
ありがとうございます。

No49880 (なちゃ さん) に返信
> 根本的にスレッドの使い方が変です。
> なぜ自分でスレッドを開始してるのに、その後わざわざ非同期実行を行って、
> しかもいきなり完了まで待ってるんでしょうか?

これの理由は2つあって、ひとつは上にもあるように4つとか複数の処理を同時に実行したいからです。
MainClass.MainはWebの巡回なので完了するのに場合によっては1時間以上かかることもあります。
この処理時間を少しでも減らすために複数のWebBrowserに分散して処理を実行したいからです。
(上のソースでは載せていませんが 4つのスレッドを生成して その4つがそれぞれ終了を待つ形になります)

2つ目は 最初非同期にはせず作っていたのですが上にもある通り処理に1時間以上かかる場合もあるので
実行中のステータスなどを画面に表示したかったのですが 同期処理だと裏で動かしているWebBrowserの処理が重いためか
画面描画が著しく遅くなったり 実行中それ以外のボタン操作などが一切できずにソフトが固まったかのように見えてしまうので
これを回避するためです。
非同期にすることで画面描画はほぼリアルタイムで反映されますし ボタン操作もできます。
ほとんどの操作ボタンは使えなくしていますが 詳細ログの表示だったり WEB巡回の中断だったりでボタンを操作するケースもあります。



> また、非同期実行してる処理はスレッドプールで実行されますのでMTAです。
> これは変えることは出来ません、STAにするには自分で作ったスレッドで明示的に設定する必要があります。

STAとかMTAとかあまりよくわかっていないのでググって調べてみたいと思います。
ありがとうございました。
引用返信 編集キー/
■49892 / inTopicNo.8)  Re[4]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (40回)-(2010/05/21(Fri) 16:33:07)
回答ありがとうございます。

No49881 (渋木宏明(ひどり) さん) に返信
>>ワーカースレッド内で WebBrowserをnewして そこで新規作成した表面上は見えないWebBrowser内で処理しているので
>
> であれば、ワーカースレッドを STA にする必要があります。
> STAThread 属性がなんなのか、どういう効果があるのかを調べてみてください。
はい、調べてみます。

> あと、なちゃさんも指摘してますが、どうしてワーカースレッドで非同期処理なんか実行しているんでしょう?
>
> 処理がワーカースレッドないで完結するのであれば、全く意味がありません。

上の回答にも書きまいたがMainClass.Mainが最短でも1分、長いと数時間に及ぶ処理のため その途中経過を画面に出力しています。
DataGridViewにあるデータを順に処理していくのですが そのステータスを実行待ち→実行中→成功(もしくは失敗)と変更したり
パフォーマンスバーを動かしたりなどしています。
なので完結しているわけではないです。

> ひょっとして、ワーカースレッドで逐次的に WebBrowser を操作するコードが期待通りの動作をしなくて、その対策だったりしますか?
きちんと書いてなかったかもしれませんが99%以上は期待通りの動作をしています。
ただ1日中まわしていてごくまれに原因不明で処理が中断したり 上のエラーが発生したりしています。
回数にしたら1日1〜2回とかです。

> であれば、それは正しい対処ではありません。
>
> WebBrowser を正しく動作させるためには、メッセージループが必要です。
>
> なので、ワーカースレッドで WebBrowser を扱うのであれば、ワーカースレッドでメッセージループを回すことになります。
>
> が、複数のワーカースレッドで独自にメッセージループを回した状態でも WebBrowser が期待通りに動作するかどうか、僕には実績がないので分かりません。

http://www.atelier-blue.com/program/mdirectx/3d/3d01-03.htm
メッセージループという単語を初めて聞いたのでググって上のサイトを見てみましたが
この場合でいうとWebBrowserで巡回させるための実行処理の命令を定期的に送ること?って理解でよろしいでしょうか?

具体的には上のthqueueってのはスレッドで実行させたい命令のqueueになっていて
非同期処理の最初にqueueの1つ目を実行すると あとはDocumentCompletedが発生すると次のqueueを実行する、という形で実装しています。
またDocumentCompletedイベントがなんらかの理由で発生しなかった時のために queueの処理の開始時にTimerをセットして
20秒たってもDocumentCompletedイベントが発生しなければエラーとして次のqueueに移動するようにしています。

>>WebBrowserでやる処理は単純なので COM使わないと、ってな自体は今のところ発生していないです。
>
> 直接使うことはなくても、不具合が発生した際に、その現象をきちんと理解するために必要になることがあります。
>
> WebBrowse を扱うのに、STAThread 属性やメッセージループが必要であることなどは、.NET の WebBrowser が、COM/OLE 技術を基盤として作られたブラウザコントロールのラッパであることに起因します。

確かにそのあたりの知識があれば今回も違った解決方法が見えてくるのかもしれませんが
現状ないものはどうしようもないので ある知識やこうして掲示板でいただいた回答をもとに部分的に調べてで
どうにか対処していこうと思っています。
引用返信 編集キー/
■49896 / inTopicNo.9)  Re[5]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ 渋木宏明(ひどり) (1334回)-(2010/05/21(Fri) 16:51:30)
渋木宏明(ひどり) さんの Web サイト
> メッセージループという単語を初めて聞いたのでググって上のサイトを見てみましたが
> この場合でいうとWebBrowserで巡回させるための実行処理の命令を定期的に送ること?って理解でよろしいでしょうか?

違います。

「メッセージループ」で適切な検索結果が得られないようなら、「メッセージポンプ」で再度調べてみてください。

> 確かにそのあたりの知識があれば今回も違った解決方法が見えてくるのかもしれませんが
> 現状ないものはどうしようもないので ある知識やこうして掲示板でいただいた回答をもとに部分的に調べてで
> どうにか対処していこうと思っています。

そうですか。

個人的には体系的に勉強した方が後々楽だと思いますが、分量が分量なので仕方がないですね。
頑張ってください。
引用返信 編集キー/
■49927 / inTopicNo.10)  Re[6]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (47回)-(2010/05/23(Sun) 14:39:33)
> なので、ワーカースレッドで WebBrowser を扱うのであれば、ワーカースレッドでメッセージループを回すことになります。

メッセージポンプについていろいろ調べてみてざっくりですがわかりました。


が おそらく私は意識していませんが ワーカースレッドを作ってwebBrowserをNewして・・・などの処理のどこかで
メッセージポンプは自動的に作られてうまく処理してくれているのではないでしょうか?
仮に手動で作らないとうまくいかない、ということであれば 私は意識して作っていませんが 99%以上うまく動作していることの説明がつかないと思うのですが・・・


オブジェクト指向プログラムって極論すれば 内部的にどんな処理がされているかって必ずしも知る必要はなくて
正しく呼び出せば正しい結果が得られる物でそれでいいと思っています。

他人の作ったプログラムを改造するとかでもソースの端から端まで全て読んでから直したりしませんよね?
一定レベル以上の開発者であれば きちんと機能ごとに分離して処理を書いているので
該当部分とその周辺を修正するだけで解決するはずです。

よっぽどマイナーなことをするのでない限り その道は誰か他の人も通った道のはずですので
同じ経験をしている人がいないかこうして掲示板で質問しています。

なおこんなこと書くと他人任せにしないで自分で・・・とか言われそうですが
情報がなく なおかつそれが必要不可欠であればとことん自分で調べます。
今はなき某PC Q&Aサイトとか出たばっかの.netframeworkの新しいバージョンのバグに悩まされながら
MSサポートに文句言いながら作ったのとか 今ではいい思い出です。



というわけで引き続き同じような現象に遭遇した覚えのある人がいましたら教えてください。
なお上で指摘されましたSTAThreadとかも試してみましたが未だに現象は回避できておりません。

引用返信 編集キー/
■49929 / inTopicNo.11)  Re[7]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ 渋木宏明(ひどり) (1337回)-(2010/05/23(Sun) 16:12:05)
渋木宏明(ひどり) さんの Web サイト
> が おそらく私は意識していませんが ワーカースレッドを作ってwebBrowserをNewして・・・などの処理のどこかで
> メッセージポンプは自動的に作られてうまく処理してくれているのではないでしょうか?

可能性は有りますが、なんとも言えません。

> 仮に手動で作らないとうまくいかない、ということであれば 私は意識して作っていませんが 99%以上うまく動作していることの説明がつかないと思うのですが・・・

そんなことはありません。
僕の経験では、メッセージポンプを回さないと「全く動かない」のではなく、「動かない時がままある」という状況でした。

とはいえ、IE4 時代の話なので、現行のブラウザコントロールの振る舞いとは異なる可能性ももちろんあります。

引用返信 編集キー/
■49939 / inTopicNo.12)  Re[8]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (48回)-(2010/05/24(Mon) 18:13:37)
回答ありがとうございます。
>とはいえ、IE4 時代の話なので、現行のブラウザコントロールの振る舞いとは異なる可能性ももちろんあります。
しかしIE4ってWindows95とかの時代ですよね?
動作は異なることの方が多い気がします。
OS自体 9X系とNT系ではまるで違うわけですし・・・



いろいろ細かくログ取って調査した結果原因 自分の単純ミスでした。

webBrowserコントロールでページの取得が非常に遅い場合にタイマーを使ってタイムアウトの処理を入れていたのですが
このアルゴリズムに問題があり タイムアウトの処理が走らないケースがあり 結果的に止まってしまっていたようです。
まだ半日ですがこの部分を直した結果 今のところエラーは発生していません。


ただそもそもwebBrowserはページの取得に失敗してもIEがエラーページを出す際にDocumentCompletedイベントが発生するのに
(LANケーブル抜いてわざとエラーにして試してみた)
なぜ発生していないんだ?って疑問は残ってしまいましたが まぁ仮に発生したとしてもエラーとして扱うことには変わりないので この実装でそのまま対応したいと思います。


いろいろご意見いただきありがとうございました。
またよろしくお願いいたします。

引用返信 編集キー/
■49940 / inTopicNo.13)  Re[9]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ 魔界の仮面弁士 (1657回)-(2010/05/24(Mon) 18:43:40)
2010/05/24(Mon) 18:47:44 編集(投稿者)

# 解決マークはまだ付いていないようなので、少し追加で:

http://msdn.microsoft.com/ja-jp/library/system.windows.forms.webbrowser%28VS.80%29.aspx
上記によれば、マネージ WebBrowser を利用する場合には、

・使用後は、必ず Dispose 相当の処理を行うこと。
・Dispose は、イベントを結びつけたスレッド上で呼び出すこと。
・イベントを結びつけるスレッドは、UI スレッド または メッセージ スレッドであること。
・利用するスレッドが、シングル スレッド アパートメント モードに設定されていること。

という注意書きがあるようですが、これらの条件は守られていますか?
引用返信 編集キー/
■49950 / inTopicNo.14)  Re[10]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (49回)-(2010/05/25(Tue) 09:57:28)
解決マーク付け忘れてました(汗



>http://msdn.microsoft.com/ja-jp/library/system.windows.forms.webbrowser%28VS.80%29.aspx
しかし貴重な情報ありがとうございます。
こういう情報待ってました。


> ・使用後は、必ず Dispose 相当の処理を行うこと。
> ・Dispose は、イベントを結びつけたスレッド上で呼び出すこと。
ワーカースレッドでDisposeしています。

> ・イベントを結びつけるスレッドは、UI スレッド または メッセージ スレッドであること。
UIスレッドではないですね。
メッセージスレッド、、、ってのは何をさすのかわからないので調べてみます。

> ・利用するスレッドが、シングル スレッド アパートメント モードに設定されていること。
こちらは上でご指摘うけたので追加しました。




引用返信 編集キー/
■49954 / inTopicNo.15)  Re[11]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ 魔界の仮面弁士 (1658回)-(2010/05/25(Tue) 11:59:32)
No49950 (たか さん) に返信
> メッセージスレッド、、、ってのは何をさすのかわからないので調べてみます。
メッセージループを回しているスレッドです。メッセージループはイベントの監視等に必要です。

C# だと、Main メソッドに
 Application.Run(new Form1());
のような記述があるかと思います。これでメッセージ ループが実行されます。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.application.run%28VS.80%29.aspx

ちなみに、Application.MessageLoop プロパティを使うと、現在のスレッドに
メッセージ ループが存在しているどうかを確認する事が出来ます。


>> ・利用するスレッドが、シングル スレッド アパートメント モードに設定されていること。
> こちらは上でご指摘うけたので追加しました。
下記に、STA / MTA に関する簡易解説があります。
http://dobon.net/vb/dotnet/form/notopenform.html#stathread
引用返信 編集キー/
■49963 / inTopicNo.16)  Re[12]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ なちゃ (437回)-(2010/05/25(Tue) 17:47:50)
すみません、■49880 の私の書き込みですが、ちょっとプログラムを読み違えていました。
デリゲートの非同期処理のBeginInvokeではなくて、コントロール(フォーム)のBeginInvokなんですね。

いや、ちょっと言い訳しておくと、

>ワーカースレッド内で WebBrowserをnewして そこで新規作成した表面上は見えないWebBrowser内で処理しているので
>プライマリスレッドのWebBrowserを呼び出しているわけではありません。
>なのでワーカースレッド終了時にDisposeしてます。

なんて書かれてるので、てっきりUIスレッドではないスレッドで非同期実行してるものだと思い込んでしまいました。
実際には、ワーカースレッドとかじゃなくて、元々のUIスレッド(メインスレッド)上でWebBrowserをnewする動作になってますよ。
そういう意味では結果的にちゃんとメッセージループのあるスレッド上で実行していることになりますが。
ただし、MainClass.MainにSTAThreadつけても意味ないです。
多分本当のMainメソッドについてるはずなので結果的には大丈夫ですが。

しかしこれ結局あまりスレッド使ってる意味なくないですか?

引用返信 編集キー/
■49967 / inTopicNo.17)  Re[13]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (51回)-(2010/05/25(Tue) 19:13:10)
>魔界の仮面弁士さん
丁寧な解説ありがとうございました。
WebBrowserの生成しているクラス内でApplication.MessageLoopの値を確認したところ無事 trueになっていることが確認できました。

STAとMTAについてもありがとうございました。
勉強になります。




引用返信 編集キー/
■49968 / inTopicNo.18)  Re[14]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ たか (52回)-(2010/05/25(Tue) 19:18:37)
>なちゃさん

自分の認識では

↓で新しいスレッドを作成
threads = new Thread(new ParameterizedThreadStart(startThreadMain));

↓は新しいスレッド内で実行されている
private void startThreadMain(Object o) {

↓のsbookは新しいスレッド上で基本的に動作し たまにFormにデータを投げる処理をする
IAsyncResult ret = this.BeginInvoke(sbook, new object[] { thqueue });

と考えていたのですが


そうするとBeginInvokeを使うと その中の処理は新しいスレッド上ではなく
基本的には投げた先(この場合だとFormのスレッド)内で動く処理 ってことでしょうか?


このあたりatmarkitとか斜め読みしてサンプル参考にトライアンドエラーで改造したので理解度特に低い部分なのですが^^



>しかしこれ結局あまりスレッド使ってる意味なくないですか?
とりあえず 非同期化の前後で目に見えてわかる違いとして上にも書きましたが以下があります。

・同時に4個の並列処理ができるようになった(マルチスレッド化)
 →前は1つずつしか処理できなかった
・WEB巡回中でもそれ以外のボタン操作ができるようになった(非同期化)
 →前はボタン操作が処理が終わるまでできなかった


引用返信 編集キー/
■49970 / inTopicNo.19)  Re[15]: 新しいスレッド上からBeginInvokeで「時々」固まる
□投稿者/ なちゃ (438回)-(2010/05/25(Tue) 19:49:43)
No49968 (たか さん) に返信
> ↓のsbookは新しいスレッド上で基本的に動作し たまにFormにデータを投げる処理をする
> IAsyncResult ret = this.BeginInvoke(sbook, new object[] { thqueue });
>
> と考えていたのですが
>
> そうするとBeginInvokeを使うと その中の処理は新しいスレッド上ではなく
> 基本的には投げた先(この場合だとFormのスレッド)内で動く処理 ってことでしょうか?

そうです。
ここは呼び出し側から見れば別のスレッド(UIのスレッド)に処理を投げているイメージですが、
あくまでUIのスレッドであって、新たに別のスレッドを使用しているわけではありません。

> >しかしこれ結局あまりスレッド使ってる意味なくないですか?
> とりあえず 非同期化の前後で目に見えてわかる違いとして上にも書きましたが以下があります。

マルチスレッドにしている意味がと言っているのであって、非同期的にすることを言っているのではありません。
もっとも、現在のコードで新たにスレッドを使っている場所での、終了処理などが長いのであれば意味はあります。
※見せていただいているコードではコメントなので、ここの処理が長いかどうかはよくわかっていませんので。

それと、以前のコードをマルチスレッドにしたから何らかの効果があった、という事実を否定しているのではなくて、
マルチスレッドにしなくても、ちゃんとうまく作ればそれで済みそうに見える、という程度の意味です。
もっとも上記のように、処理の開始と終了処理に時間がかかるのであれば、マルチスレッドにすることには意味がありますし、
そうでなくてもコードがシンプルにわかりやすくなる場合もありますので、一概に否定する意図はありません。

開始終了処理に時間がかからないのであれば、特にマルチスレッドにする「必要性」は感じない、という程度ですかね。
※特にマルチスレッドにしなくても、普通に作れそうに見える、くらいの言い方なら通じますかね?
引用返信 編集キー/
■49973 / inTopicNo.20)  Re[16]: 新しいスレッド上からBeginInvokeで「時々」固まる
 
□投稿者/ たか (53回)-(2010/05/25(Tue) 20:22:43)
>なちゃさん
回答ありがとうございます。
かなりすっきりしました。

自分のBeginInvokeに対する理解が間違ってたから上の質問・回答でも食い違ってる部分ができていたわけですね。
言葉足らずな部分もあったりで申し訳ございませんでした。

> 開始終了処理に時間がかからないのであれば、特にマルチスレッドにする「必要性」は感じない、という程度ですかね。
> ※特にマルチスレッドにしなくても、普通に作れそうに見える、くらいの言い方なら通じますかね?
上の回答のどこかにも少し書きましたがMainClass,MainはWEBの巡回なので 長いときは完了までに1時間以上かかったりします^^
最短でも1分弱とかで・・・
処理が重たい、、、というより いろんなページを回るのでレスポンス待ちが長いという感じですが・・・


なので非同期にして進行状況をパフォーマンスバーや画面内に出さないと どう見てもソフトがフリーズしているようにしか見えないので 非同期化しました。 非同期化しないと処理の中断ボタンも押せない、なんてこともあったりで・・・



>回答いただいたみなさま
自分の理解不足や言葉足らずで誤解させてしまったりしてしまい申し訳ございませんでした。
そしていろいろ教えていただいてありがとうございました。

これをもちまして解決としたいと思います。

またよろしくお願いいたします。
解決済み
引用返信 編集キー/

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

管理者用

- Child Tree -