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

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

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

Re[13]: スレッドの利用・使い方


(過去ログ 27 を表示中)

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

■12362 / inTopicNo.1)  スレッドの利用・使い方
  
□投稿者/ りお (17回)-(2008/01/08(Tue) 17:07:52)

分類:[C#] 

いつもお世話になります。りおです。

特定のフォルダを常時監視し、特定ファイルが作成されたタイミングで
報告処理を行うプログラムを開発しています。

監視先のディレクトリは下記のようになっていて、それぞれの配下に特定ファイルが作成されます。
  C:\TEST\001
      \002
      \003
      …

●現状
メイン{
  フォルダ監視("C:\TEST")
}

フォルダ監視(string chkPATH){
  if (特定ファイルの作成をチェック) {
      // 作成された時
      報告処理実行
  }
  フォルダ監視(再帰)
}

上記のように作成したのですが、報告処理の実行中に、他のディレクトリにも
特定ファイルが作成されると、そちらの報告処理に対応できません。

そこで、フォルダ監視は常に行えるようにしたいので、
報告処理は別スレッドとして起動させれば良いと思い試したのですが、
どうしたら動くのか分かりません。

●改善(これで出来るか不明ですが…)

メイン{
  フォルダ監視(@"C:\TEST")
}

フォルダ監視(string chkPATH){
  特定ファイル作成された! → スレッド(報告処理)実行する

  フォルダ監視(再帰)
}

報告処理{
  報告ファイルを作成する などなど
}


分かり辛い質問で申し訳ありませんが、
001フォルダに特定ファイルが作成され、報告処理を行っている時でも、
002フォルダに特定ファイルが作成されたら、こっちの報告処理も行えるように
常に監視を行っていけるようにしたいです。

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

引用返信 編集キー/
■12363 / inTopicNo.2)  Re[1]: スレッドの利用・使い方
□投稿者/ 囚人 (275回)-(2008/01/08(Tue) 17:26:07)
こちらも完璧な報告をしてくれないらいしいですが、FileSystemWatcher クラスというものがあります。まずはご参考まで。

本題。

別スレッドでディレクトリを監視し、変化があれば、スタックなどのデータ構造に変化状況を積んでいく。
メインスレッドはときどきスタックを見て、変化があれば処理を行う。

という感じでいかがでしょう。


でも

>上記のように作成したのですが、報告処理の実行中に、他のディレクトリにも
>特定ファイルが作成されると、そちらの報告処理に対応できません。

は、単に監視の仕方が悪いって気もしますね。どうやってるんでしょう?

引用返信 編集キー/
■12370 / inTopicNo.3)  Re[2]: スレッドの利用・使い方
□投稿者/ りお (19回)-(2008/01/08(Tue) 18:29:49)
囚人さん、ありがとうございます。

完璧な報告をするには、あまり見せられたソースじゃなくて、、、
ものすごく長いロジックになってますのでご容赦ください。m(__)m

参考に挙げていただいたFileSystemWatcher クラスですが、
http://dobon.net/vb/dotnet/file/filesystemwatcher.html
のサイトの公開ソースを有用させて頂きました。
case System.IO.WatcherChangeTypes.Created:
に入ったときに報告処理を入れ込んでいます。

>は、単に監視の仕方が悪いって気もしますね。どうやってるんでしょう?
はい、監視の仕方が悪いと思います。
上で挙げた「●現状」のようになっていますので、特定ファイルが同時に
出来たときに希望通りに動きません…。

001フォルダ・002フォルダ配下それぞれに同時に特定ファイルを作りましたら、
001フォルダの報告処理しか行いませんでした。。
スレッドを用いたら、この問題に対応可能かと思ったのですが、
間違いでしょうか。

ときどきスタックを見るやり方も、まだ分かってないのですが、
出来れば、リアルタイムが希望です。。

お手数おかけしますが、宜しくお願いします。

引用返信 編集キー/
■12374 / inTopicNo.4)  Re[3]: スレッドの利用・使い方
□投稿者/ Hirotow (128回)-(2008/01/08(Tue) 18:51:29)
No12370 (りお さん) に返信
> ときどきスタックを見るやり方も、まだ分かってないのですが、
> 出来れば、リアルタイムが希望です。。
>
> お手数おかけしますが、宜しくお願いします。
>
BackgroundWorkerとTimerを使えばいいと思います。
BackgroundWorkerのDoWorkイベントでTimerを初期化および作動し、そのTimerのTickイベントでスタックを確認、処理します。

引用返信 編集キー/
■12379 / inTopicNo.5)  Re[3]: スレッドの利用・使い方
□投稿者/ Jitta (445回)-(2008/01/08(Tue) 21:39:23)
Jitta さんの Web サイト
No12370 (りお さん) に返信
 ファイルの変更監視は、ちょっと工夫が必要です。というのも、変更が検知されたときが、ファイルの変更が完了したときではないからです。

 ちょっと考えてみてください。ファイルに何かを書き込むとき、まず open 命令を発行します。そして、実際に中身を書き込みます。最後に、close します。ファイルを変更したとして検出されたいときは、close 命令が発行されたときのはずです。しかし、実際には open 命令や write 命令を検出するでしょう。


 ちょっと気になったのが、「フォルダ監視(再帰)」です。再帰って、なぜ?これだと、そのうち Stack Overflow をおこしますよ?

引用返信 編集キー/
■12381 / inTopicNo.6)  Re[4]: スレッドの利用・使い方
□投稿者/ れい (358回)-(2008/01/08(Tue) 22:38:20)
ファイルシステムというのは仕組み上常時監視というタスクは苦手なんです。
そもそもプロセス間の通信にファイルの存在を用いるのはナンセンスなので、
パフォーマンスをあげるために常時監視などは考慮されていません。

無理に実装するとえらく手間がかかってしまいます。
FileSystemWatcherもきちんと監視できませんし、
定期的に見るのもうまく行かないときがあるし。

常時監視はダメな方向なので、私はほぼ使いません。
できれば違う方向で考えたほうがいいかと思います。

でももしやるとするなら。
話を聞く限りでは監視スレッドと報告スレッドにわける、
りおさんのやり方がよいであろうと思います。

スレッドプールからスレッドを拾ってもよいと思いますし、
BackgroundWorkerを起動してもいいですし、
独自のスレッドを作っても、大して手間は変わりませんが、
スレッドプールを使うのが一番楽でしょう。

スレッド処理に慣れていないのでしたら
自分でスレッドを作るのが良いと思います。
スレッドプールもBackgroundWorkerも、
スレッドをきちんと理解してないと使えません。

また、BackgroundWorkerはいろいろ嫌な点があるので私なら使いません。

それと、「報告処理」の内容によっては
スレッドなど使わないほうがいい場合も多々あります。
スレッドはいろいろコストが大きいので、(CPU時間とか人的資源とか精神力とかいろいろ。)
できれば避けるべきです。

つまり私なら

・ファイルの常時監視はなるべくしない。
・同時に作業させたいからといってすぐにスレッドに手を出したりしない。

りおさんのやり方とは完全に逆の方向に舵を取ると思います。

#いろいろな外部要因で最終的に同じ方向に進むかもしれませんが。

引用返信 編集キー/
■12405 / inTopicNo.7)  Re[3]: スレッドの利用・使い方
□投稿者/ y4yama (49回)-(2008/01/09(Wed) 13:40:58)
No12370 (りお さん) に返信
> >は、単に監視の仕方が悪いって気もしますね。どうやってるんでしょう?
> はい、監視の仕方が悪いと思います。
> 上で挙げた「●現状」のようになっていますので、特定ファイルが同時に
> 出来たときに希望通りに動きません…。
この文面では、「どうやってるんでしょう?」への返事とは理解できませんです

> 001フォルダ・002フォルダ配下それぞれに同時に特定ファイルを作りましたら、
> 001フォルダの報告処理しか行いませんでした。。
だから、監視の仕方が悪いのでしょう(・・もしかして、Nowと同じ時刻(秒)だけのファイルを探しているとか)

りおさんは、 特定ファイルが作成されたタイミングで と言われています。単純にはファイル名だけで
捕まえられそうですが(当方、無知なものでして)
・同じファイル名だが、タイムスタンプが違う
・ファイルが作成されて、数十ミリ秒後には消される(のも補足したい?)
という懸念が在るのか無いのか・・
もっと具体的に説明しないと、話は拡がるばかりで・・・デス
引用返信 編集キー/
■12452 / inTopicNo.8)  Re[4]: スレッドの利用・使い方
□投稿者/ りお (20回)-(2008/01/09(Wed) 20:17:28)
皆さん、アドバイスありがとうございます。

■No12374 (Hirotow さん) に返信

BackgroundWorkerとTimerの手段を用いたら上手く行くかも知れません。
使ったこと無いので先ず勉強します。m(__)m

■No12379 (Jitta さん) に返信

検出タイミングの問題ですね。
今は検出タイミングについて問題発生していませんので大丈夫だと思います。
ただし、運用させてから実際どうなるか確認とれていないので、
作成手段によっては問題になりそうなので気をつけます。

再起にした理由は、フォルダの変化が発生すると、イベントを発見→処理終了・・・。
となるので再起するようにしました。
Stack Overflow を起こしてしまいますか…、ずっと監視したいので再起以外に手段が分かりません。

■No12381 (れい さん) に返信

> スレッドをきちんと理解してないと使えません。
スレッドを理解したいのですが、なかなか難しいです。

スレッドを避けたいのですが、リアルタイムで常に監視するシステムなので
避けることは出来ないと思います。なんとか頑張りたいです。

■No12405 (y4yama さん) に返信

> りおさんは、 特定ファイルが作成されたタイミングで と言われています。単純にはファイル名だけで
> 捕まえられそうですが(当方、無知なものでして)
特定ファイルはファイル名が"CHECK.DAT"です。
FileSystemWatcher でCreateを取得したら、
ファイル名が"CHECK.DAT"のときに報告処理を行います。
そして報告処理で"CHECK.DAT"は削除します。
なので
> ・同じファイル名だが、タイムスタンプが違う
> ・ファイルが作成されて、数十ミリ秒後には消される(のも補足したい?)
どちらの概念もありません。

> もっと具体的に説明しないと、話は拡がるばかりで・・・デス
はい、以下のようになります。説明不足がありましたら、突っ込んでくださいm(__)m

  C:\TEST\001
      \002
      \003
      ↑(他のシステムがこの配下に"CHECK.DAT"を作ってくるので、
        これの監視をします。作成された時、報告処理を実行)

●現状
メイン{
  フォルダ監視(@"C:\TEST")
}

フォルダ監視(string chkPATH){
  if (特定ファイル"CHECK.DAT"作成をチェック) {
      // 作成された時
      報告処理();
  }
  フォルダ監視(再帰)
}

報告処理() {
  ・"CHECK.DAT"の同階層フォルダに存在するファイルをZIP圧縮し、ZIP出力
  ・圧縮ファイルの内容一覧ファイルを出力
  ・"CHECK.DAT"の同階層フォルダに存在するファイルをすべて削除
}


C:\TEST\001配下に"CHECK.DAT"が作られたら、報告処理を行いますが、
報告処理中には、他ディレクトリの監視が行われなくなってしまいます。

引用返信 編集キー/
■12478 / inTopicNo.9)  Re[5]: スレッドの利用・使い方
□投稿者/ y4yama (50回)-(2008/01/10(Thu) 08:45:41)
No12452 (りお さん) に返信
> スレッドを避けたいのですが、リアルタイムで常に監視するシステムなので
> 避けることは出来ないと思います。なんとか頑張りたいです。
単純に、スレッドなど作らないでできそうですヨ!
「リアルタイムで常に」は以下のように疑問がありますが・・・

> ■No12405 (y4yama さん) に返信
> 特定ファイルはファイル名が"CHECK.DAT"です。
> FileSystemWatcher でCreateを取得したら、
> ファイル名が"CHECK.DAT"のときに報告処理を行います。
> そして報告処理で"CHECK.DAT"は削除します。
自分の世界で"CHECK.DAT"を削除するんですね。これは、とてもやりやすい前提条件と思います

> どちらの概念もありません。
概念でなく、懸念(=心配)です

> 報告処理() {
>   ・"CHECK.DAT"の同階層フォルダに存在するファイルをZIP圧縮し、ZIP出力
>   ・圧縮ファイルの内容一覧ファイルを出力
>   ・"CHECK.DAT"の同階層フォルダに存在するファイルをすべて削除
> }
多分、前段階のシステムで同階層フォルダに存在するファイルsをここにCopyされた後で、"CHECK.DAT"というコマンドカード的な
目印とするファイルが作られるんだと推察します。だから"CHECK.DAT"が「存在」したら、その後でここに
追加のデータファイルはCopyされることはない、ということだと思いました(違ってたら、報告処理はうまく処理できないです)

> C:\TEST\001配下に"CHECK.DAT"が作られたら、報告処理を行いますが、
> 報告処理中には、他ディレクトリの監視が行われなくなってしまいます。
他ディレクトリは、あとから見ても、他の人が消すわけではないですよね
だから、10分後に見ても、"CHECK.DAT"があるのであれば、監視が可能でしょう?
(私に、りおさんが「監視」と言われていることの意味が解かってないのでしょうか?)
れいさんが、
・同時に作業させたいからといってすぐにスレッドに手を出したりしない。
と言われているので(同感です)、ここに言及したいのですが
1つの階層フォルダの報告処理に時間が5分かかるとして、次の階層フォルダの報告処理に取り掛かるのはその後では
まずいのですか?
同時に作業といっても、別CPUに分散させるのでなかったら、1つのCPUでは 5分が長くなることはあっても速くはならないですよネ

ちょうど、去年、似たようなシステムを作り(シロート的にですが)、24Hフルに運用してます
Timerで5秒毎に、複数のフォルダを調べて、"CHECK.DAT"があればそこに書かれているファイルを圧縮する・・というので
問題なく稼動してます
引用返信 編集キー/
■12509 / inTopicNo.10)  Re[6]: スレッドの利用・使い方
□投稿者/ 七曜 (31回)-(2008/01/10(Thu) 18:49:45)
そもそも1プロセスで複数のフォルダを監視しなければならないのでしょうか。
監視するフォルダ数によっては、プロセス数が多くなりすぎるのであまり良いアイデアではないのですが、
1プロセスで1フォルダを監視するのであれば、同時処理はあまり意識しなくても良くなりますよね。

で、おそらく常駐プロセスみたいな感じなので
引数に監視フォルダパスと監視間隔を指定出来るようにしておいて、
(1)ファイルがあるか確認する。
(2)ファイルがあったら、あった場合の処理をする。なかった場合は何もしない。(ログ書いても良いですよ。)
(3)Thread.Sleepあたりで、次の監視間隔まで寝かせておく。
(4)(1)へ戻る。
としておけば、複数のフォルダに同時にファイルが生成されても、プロセスが分離されていますから
それぞれが独立して処理されますよね。

で、懸念事項と言えば、(2)の処理中に、そのフォルダに変更がかかる事があるとちょっと考慮が必要になるかもしれません。

これだとスレッドのことをあまり考えなくっても良いですしね。
引用返信 編集キー/
■12569 / inTopicNo.11)  Re[7]: スレッドの利用・使い方
□投稿者/ りお (21回)-(2008/01/11(Fri) 17:28:09)
y4yamaさん、七曜さん、アドバイスありがとうございます。

No12478 (y4yama さん) に返信
> 概念でなく、懸念(=心配)です
ごめんなさい、読み間違いしました(^^;

> 多分、前段階のシステムで同階層フォルダに存在するファイルsをここにCopyされた後で、"CHECK.DAT"というコマンドカード的な
> 目印とするファイルが作られるんだと推察します。だから"CHECK.DAT"が「存在」したら、その後でここに
> 追加のデータファイルはCopyされることはない、ということだと思いました(違ってたら、報告処理はうまく処理できないです)
はい、前段階のシステムの動きはそうなります。(このファイルをトリガーとして処理する動き)

> 他ディレクトリは、あとから見ても、他の人が消すわけではないですよね
はい、他の人が消すことはありません。

> だから、10分後に見ても、"CHECK.DAT"があるのであれば、監視が可能でしょう?
> (私に、りおさんが「監視」と言われていることの意味が解かってないのでしょうか?)
はい、監視可能です。

> れいさんが、
> ・同時に作業させたいからといってすぐにスレッドに手を出したりしない。
> と言われているので(同感です)、ここに言及したいのですが
すぐにスレッドに手を出したりしない。←同感です。スレッドの技術を身につけたいです。

> 1つの階層フォルダの報告処理に時間が5分かかるとして、次の階層フォルダの報告処理に取り掛かるのはその後では
> まずいのですか?
「リアルタイムで"CHECK.DAT"が作成された時に報告処理を実行するように」と上役からの要望なので、
時間がかかってから次の階層フォルダの報告処理に取り掛かるのは要望を満たせません…。
しかし、リアルタイムではなく一定間隔の監視する手段への変更したいと思います。上役に相談してみます。

> 同時に作業といっても、別CPUに分散させるのでなかったら、1つのCPUでは 5分が長くなることはあっても速くはならないですよネ
そうですね。

> ちょうど、去年、似たようなシステムを作り(シロート的にですが)、24Hフルに運用してます
> Timerで5秒毎に、複数のフォルダを調べて、"CHECK.DAT"があればそこに書かれているファイルを圧縮する・・というので
> 問題なく稼動してます
実績のお話ありがとうございます☆私も早く稼動させたいです(^^)

No12509 (七曜 さん) に返信
> そもそも1プロセスで複数のフォルダを監視しなければならないのでしょうか。
> 監視するフォルダ数によっては、プロセス数が多くなりすぎるのであまり良いアイデアではないのですが、
> 1プロセスで1フォルダを監視するのであれば、同時処理はあまり意識しなくても良くなりますよね。
監視するフォルダを
 C:\TEST\001  1スレッド
 C:\TEST\002  2スレッド
 C:\TEST\003  3スレッド
として動かせば、1プロセス1フォルダになりますね。
これで3プロセスになりますが、最大いくつのプロセスまで動かすことが出来るのでしょうか…?
そもそもスレッドはいくつまでの動作に耐えられるのでしょう…。

> で、懸念事項と言えば、(2)の処理中に、そのフォルダに変更がかかる事があるとちょっと考慮が必要になるかもしれません。
"CHECK.DAT"が存在しているので、処理中のフォルダへの変更は発生しません。


--------------------------------------------------
まだスレッドに手を出す方向で、もう少し頑張りたいと思います。ただいま、スレッドの勉強してます^^;
引き続きアドバイス頂けたら助かりますので、宜しくお願いします。

引用返信 編集キー/
■12573 / inTopicNo.12)  Re[8]: スレッドの利用・使い方
□投稿者/ 魔界の仮面弁士 (568回)-(2008/01/11(Fri) 18:14:38)
No12569 (りお さん) に返信
> 監視するフォルダを
>  C:\TEST\001  1スレッド
>  C:\TEST\002  2スレッド
>  C:\TEST\003  3スレッド
> として動かせば、1プロセス1フォルダになりますね。
> これで3プロセスになりますが、最大いくつのプロセスまで動かすことが出来るのでしょうか…?

「プロセス数」の話ですか?
「スレッド数」の話ですか?

# 1 つのプロセスから、複数のスレッドを立ち上げて監視するのか、
# それとも、複数のプロセスを使って監視させるのか…。
引用返信 編集キー/
■12693 / inTopicNo.13)  Re[9]: スレッドの利用・使い方
□投稿者/ りお (22回)-(2008/01/15(Tue) 12:23:54)
No12573 (魔界の仮面弁士 さん) に返信
> 「プロセス数」の話ですか?
> 「スレッド数」の話ですか?
> 
> # 1 つのプロセスから、複数のスレッドを立ち上げて監視するのか、
> # それとも、複数のプロセスを使って監視させるのか…。
すいません、1プロセスnスレッドでした。

やっとスレッドによる監視ができました。
ソースを一部略(報告メソッド)しますが、下記のようになりました。

これで、正常動作できました。
皆様、ありがとうございました☆

///////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;

/*
 * スレッドを用いてフォルダ監視を行ってみる
 */
namespace TEST {
    class Program {
        // メイン
        static int Main(string[] args) {

            // 親監視フォルダより、各監視対象フォルダ毎にスレッド実行
            foreach (string stDirPath in System.IO.Directory.GetDirectories(@"C:\TEST\", "*")) {

                KansiThreadinfo info = new KansiThreadinfo(stDirPath);

                System.Threading.Thread tKANSI = 
                    new System.Threading.Thread(
                    new System.Threading.ThreadStart(info.tKANSI));

                tKANSI.Start();
            }

            return 0;
        }
    }

    /*
     * 監視を行うクラス(監視のスレッド)
     */
    class KansiThreadinfo {

        // スレッドに渡す値
        string wkKansipath;

        // インストラクタ
        public KansiThreadinfo(string kansipath) {
            this.wkKansipath = kansipath;
        }

        /*
         * 監視スレッド
         */
        public void tKANSI() {

            try {
                System.IO.FileSystemWatcher watcher = 
                    new System.IO.FileSystemWatcher();

                // 監視するディレクトリを設定
                watcher.Path = wkKansipath;

                // ファイル名とディレクトリ名と最終書き込む日時の変更を監視
                watcher.NotifyFilter =
                    System.IO.NotifyFilters.FileName
                    | System.IO.NotifyFilters.DirectoryName
                    | System.IO.NotifyFilters.LastWrite;

                // サブディレクトリ監視設定
                watcher.IncludeSubdirectories = false;    // 監視しない

                // 必要に応じてバッファサイズを変更
                //watcher.InternalBufferSize = 4096

                // 同期的に監視を開始する
                System.IO.WaitForChangedResult changedResult =
                    watcher.WaitForChanged(System.IO.WatcherChangeTypes.All);

                // タイムアウトチェック
                if (changedResult.TimedOut) {
                    // タイムアウトしても再帰(要検討)
                    tKANSI();
                }

                // フォルダ配下の変更イベント取得
                switch (changedResult.ChangeType) {
                    case System.IO.WatcherChangeTypes.Created:
                        if (changedResult.Name == "CHECK.DAT") {
                            // 報告処理
                            HokoThreadinfo hokoinfo = new HokoThreadinfo(wkKansipath);

                            // tHOKOメソッドを別のスレッドで実施する
                            System.Threading.Thread tHOKO =
                                new System.Threading.Thread(
                                new System.Threading.ThreadStart(hokoinfo.tHOKO));

                            tHOKO.Start();
                            tHOKO.Join();
                        }
                        break;
                    case System.IO.WatcherChangeTypes.Changed:
                        break;
                    case System.IO.WatcherChangeTypes.Deleted:
                        break;
                    case System.IO.WatcherChangeTypes.Renamed:
                        break;
                    default:
                        break;
                }

                // 再帰
                tKANSI();
            }
            catch (Exception e) {
                // エラーになっても再帰(要検討)
                tKANSI();    // 再帰
            }
        }
    }

    /*
     * 報告処理を行うクラス(報告処理のスレッド)
     */
    class HokoThreadinfo {

        // スレッドに渡す値
        string wkKansipath;

        // インストラクタ
        public HokoThreadinfo(string kansipath) {
            this.wkKansipath = kansipath;
        }

        /*
         * 報告メソッド
         */
        public void tHOKO() {
            ・"CHECK.DAT"の同階層フォルダに存在するファイルをZIP圧縮し、ZIP出力
            ・圧縮ファイルの内容一覧ファイルを出力
            ・"CHECK.DAT"の同階層フォルダに存在するファイルをすべて削除
        }
    }
}

解決済み
引用返信 編集キー/
■12695 / inTopicNo.14)  Re[10]: スレッドの利用・使い方
□投稿者/ れい (366回)-(2008/01/15(Tue) 13:02:58)
No12693 (りお さん) に返信
> これで、正常動作できました。

ぱっと見たところ、
正常動作するとは思えません。

No12379 (Jitta さん) に返信
>  ちょっと気になったのが、「フォルダ監視(再帰)」です。再帰って、なぜ?これだと、そのうち Stack Overflow をおこしますよ?

ここ、ちゃんと理解しましたか?
引用返信 編集キー/
■12705 / inTopicNo.15)  Re[11]: スレッドの利用・使い方
□投稿者/ りお (23回)-(2008/01/15(Tue) 15:10:32)
れいさん、ありがとうございます。

No12695 (れい さん) に返信
> ぱっと見たところ、
> 正常動作するとは思えません。


> ■No12379 (Jitta さん) に返信
>> ちょっと気になったのが、「フォルダ監視(再帰)」です。再帰って、なぜ?これだと、そのうち Stack Overflow をおこしますよ?
>
> ここ、ちゃんと理解しましたか?
理解できているか自身はありませんが、調べてみました。

なんどか動かしてみましたがstack Overflowのエラーは発生しません。

ただし、CHECK.DAT作成→削除を繰り返して何度も再帰をさせながら、「Windowsタスクマネージャ」→「パフォーマンス」
を確認したところ、ハンドルの値が毎回少しだけあがり、下がりません。
これが問題なのでしょうか…?ハンドルを元の値に戻すには何か方法はあるのでしょうか?
引用返信 編集キー/
■12707 / inTopicNo.16)  Re[12]: スレッドの利用・使い方
□投稿者/ なちゃ (98回)-(2008/01/15(Tue) 15:37:18)
んーちとまずい方向に行ってる気がします。
いわゆるスレッドを濫用してまずい方向に行くパターンな気が…

引用返信 編集キー/
■12708 / inTopicNo.17)  Re[12]: スレッドの利用・使い方
□投稿者/ れい (367回)-(2008/01/15(Tue) 15:39:10)
No12705 (りお さん) に返信
> なんどか動かしてみましたがstack Overflowのエラーは発生しません。

.Netのスタックも1回の呼び出しにどのくらいスタックを使うのかも覚えてませんが、
なんどか、というレベルで再現できるとは思えません。

ですが、当然無限の深さを扱えるわけではありませんし、
監視をしたいのでしたら長時間稼動させるでしょうから、
考慮しておかなければいけません。

> ハンドルの値が毎回少しだけあがり、下がりません。
> これが問題なのでしょうか…?ハンドルを元の値に戻すには何か方法はあるのでしょうか?

そこ「も」問題です。
オブジェクトは使ったらきちんと廃棄する必要があります。
関数呼び出しは深くならないようにします。
監視してる間中ずっと増えっぱなし、深くなりっぱなしではいつか止まります。

再帰で呼ぶのではなく、ループを使い、FileSystemWatcher.Disposeもしくは
Component.Dispose/IDisposable.Disposeを調べるとよいと思います。



引用返信 編集キー/
■12714 / inTopicNo.18)  Re[13]: スレッドの利用・使い方
□投稿者/ りお (25回)-(2008/01/15(Tue) 17:30:19)
なちゃさん、れいさん、ありがとうございます。m(__)m

No12707 (なちゃ さん) に返信
> んーちとまずい方向に行ってる気がします。
> いわゆるスレッドを濫用してまずい方向に行くパターンな気が…
まずい方向に行きかけてましたね(・_・;
スレッドの終了が出来ていなかったので見直します。

No12708 (れい さん) に返信
なんども処理を実行したら、どんどんハンドルが上がってました。
これに気づかずに再帰させていれば、使い物にならないモノになってますね。

> 再帰で呼ぶのではなく、ループを使い、FileSystemWatcher.Disposeもしくは
> Component.Dispose/IDisposable.Disposeを調べるとよいと思います。
はい、再帰の手段は止めます。
そちらのメソッドを調べてループさせるようにソースを変更して
動作確認してみます。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -