3

FileSystemWatcher をセットアップするアプリがあります。無期限に実行する必要があります。

アイドルループで実行する最良の方法は何ですか?

私は現在やっています

FileSystemWatcher watch = ... //setup the watcher
watch.EnableRaisingEvents = true;
while (true) 
{
    Thread.Sleep(int.MaxValue);
}

これは機能しているようです (つまり、イベントをキャプチャし、ビジー ループでコアを使い果たしません)。

他の慣用句はありますか?このアプローチに問題はありますか?

4

5 に答える 5

9

FileSystemWatcher.WaitForChanged がブロックされています(同期)。特にイベントを処理しているため、アイドル ループはまったく必要ありません。注 EnableRaisingEvents のデフォルトは true です。したがって、コンポーネントをフォームに追加するだけです。アイドルループはありません。コンポーネントがそれを処理するため、スレッド化はありません。

コンソール アプリケーションを使用しているとのことですが、したがって、次のループを作成できます。繰り返しますが、アイドル ループは必要ありません。コンポーネントはすべての詳細を処理します。

    Do
        Dim i As WaitForChangedResult = Me.FileSystemWatcher1.WaitForChanged(WatcherChangeTypes.All, 1000)
    Loop Until fCancel

[更新] 「EnableRaisingEvents のデフォルトは true に注意してください。」Microsoft ソース コードによると、これは FileSystemWatcher コンポーネントがデザイナーにドロップされた場合にのみ当てはまります。以下に示すように:

    /// <internalonly/>
    /// <devdoc>
    /// </devdoc>
    [Browsable(false)] 
    public override ISite Site {
        get { 
            return base.Site; 
        }
        set { 
            base.Site = value;

            // set EnableRaisingEvents to true at design time so the user
            // doesn't have to manually. We can't do this in 
            // the constructor because in code it should
            // default to false. 
            if (Site != null && Site.DesignMode) 
                EnableRaisingEvents = true;
        } 
    }

[更新] 呼び出しWaitForChangedは、ステートメントの直前と直後に EnableRaisingEvents を設定しますSystem.Threading.Monitor.Wait

于 2009-09-14T10:12:43.330 に答える
5

あなたのコメントから理解したように、アプリケーションを無期限に実行する必要があり、それは別の実行可能ファイルによって起動されるコンソール アプリです。

ループする代わりに、Console.ReadLine を使用することをお勧めします。または Monitor.Wait メソッドを使用して、スレッドを無期限にブロックします

object sync = new object();
lock(sync)
Monitor.Wait(sync);
于 2009-09-14T10:11:34.863 に答える
2

Thread.Sleep() はあなたが望むことをします。ただし、基本的には、目的の戦略で起動する OS メソッドを使用してブロックする必要があります。例えば。Console.ReadLine() または、イベント ハンドラーによってヒットされて消えるミューテックス。

アプリを閉じるためにアプリを強制終了する必要はありません。

コードをフォームに埋め込むと、少なくともフォームを適切に強制終了することができ、使用していないときは適切な OS 負荷がかかります。

于 2009-09-14T09:54:48.287 に答える
2

このループが実行されているスレッドをバックグラウンド スレッド ( Thread.IsBackground プロパティ) としてマークすると、正常に動作するはずです (バックグラウンド以外のすべてのスレッドが終了すると、プログラムは終了します)。

于 2009-09-14T09:58:43.380 に答える
0

わかりません...なぜアイドルループが必要なのですか?アプリケーションを無期限に実行しますか?

では、Windows サービス、またはシステム トレイで実行できるアプリケーションを作成してみませんか?

次に、これを行うクラスを作成します。

public class Foo
{
   private FileSystemWatcher _fs;

   private volatile bool _stopped = false;

   public Foo()
   {
       _fs = new FileSystemWatcher();
       ...
   }

   public void Start()
   {
       _stopped = false;
       Thread t = new Thread (new ThreadStart(DoWork));
       t.Start();
   }

   private void DoWork()
   {
       while( !_stopped )
       {
           Thread.Sleep(1);
       }
   }

   public void Stop()
   {
       _stopped = true;
   }

}
于 2009-09-14T09:55:43.463 に答える