4

いくつかのファイル、フォルダー、および DB テーブルの変更を監視する c# Windows サービスを開発しています。ウォッチャーには 3 種類あります (私はウォッチャーと呼んでいます)。

  1. FileWatcher : .Net FileSystemWatcherを使用して常にファイルを監視し、アラートが送信されるイベントを発生させます。アラートが送信された後、時計機能が再開されます。

  2. FolderWatcher : .Net Timerを使用してフォルダーを常に監視し、特定の条件でアラートが送信されるイベントを発生させます。アラートが送信された後、時計機能が再開されます。

  3. DBWatcher : 毎分 (タイマー) ごとに SQL クエリを実行し、結果が間違っている場合はアラートを送信します。

これらすべてのウォッチャーは、Windows サービスが実行されている場所で常に実行されると推測できます。

それらはすべてインターフェイスIWatcherを実装し、タイマーを使用して毎分 DB を照会するなど、各ウォッチャーに必要な操作を実行するメソッドBeginWatchを提供します(ウォッチャーが DBWatcher の場合)。これらのウォッチャーを作成するための入力は XML ファイルです。次のようなものが含まれています。

<?xml version="1.0" encoding="utf-8"?>
<watchlist>

    <watcher type="FolderWatcher">
        <path>D:\Projects\.Net\V1\</path>
        <PauseInMinBtwAlerts>1</PauseInMinBtwAlerts>
        <alert>xxx@xxx.com</alert>
    </watcher>

    <watcher type="FileWatcher">
        <path>D:\Projects\.Net\</path>
        <fileName>e.txt</fileName>
        <alert>yyy@yyy.com</alert>
    </watcher>

    <watcher type="DBWatcher">
        <sqlquery>select blah blah blah ... </sqlquery>
        <connectionstring>connection string for the DB</connectionstring>
        <alert>yyy@yyy.com</alert>
    </watcher>

</watchlist>

この XML は、作成するウォッチャーの数を示します。多数のウォッチャーが作成される場合があります。

いくつかの問題が発生したため、各ウォッチャーを異なるスレッドで実行することにしました。そのため、未処理の例外が発生した場合、そのスレッドのみを停止/強制終了することができ、電子メール アラートを通じて IT 部門に状況を通知します。後で再開できるはずです。

今、私は混乱しています。スレッド、非同期タスク、プールされたスレッド、バックグラウンド スレッドなどがあります。何を使用すればよいですか???/ このスレッドは初めてです。

私の要件を教えてください。その後、いくつかの適切な解決策を案内してください。

  1. 各ウォッチャーを個別のスレッドで実行したい。
  2. スレッドは継続的に実行する必要があり、ウォッチャーは Windows サービス自体がシャットダウンするまで監視できる必要があります。
  3. スレッドは、親スレッド (各スレッドが作成されるクラス) と通信して、そのステータスを更新できる必要があります。
  4. スレッド内の未処理の例外は、スレッド自体でキャッチしてから、親クラスに伝達する必要があります (3 番目のポイントを使用)。

すべてのスレッドの作成、通信、および管理を担当する次のクラスを作成しました。

public class WatcherThreadsManager
{
    //This will keep list of all active threads ... as I will be communicating with them later
    private List<Thread> _watcherThreads;

    public WatcherThreadsManager()
    {
        this._watcherThreads = new List<Thread>();
    }

    //I will call this method and pass in any watcher which i want to run in a new thread
    public void CreateWatcherThread(IWatcher watcher)
    {
        Thread _watcher = new Thread(_createWatcherThread);

        //the Copy() will produce its deeply copied copy ... i wanted to make sure thread works on a free object .. not sure
        _watcher.Start(watcher.Copy());

        //Add Thread to threads' list
        this._watcherThreads.Add(_watcher);
    }

    private void _createWatcherThread(object wat)
    {
        IWatcher watcher = wat as IWatcher;
        try
        {
            //the following function will begin the watch.
            //I dont want any loop either .. as i want to call the BeginWatch() method only once.
            watcher.BeginWatch();
        }
        catch (Exception ex)
        {
            // i should be able to inform the parent thread about the exception so this thread is set to sleep. as we can reactivate it later when the issue fixes.
            // how to do that?
        }
    }
} 

私が望むものを達成するための最良の方法は何ですか?

4

2 に答える 2

4

タスクを使用してすべての要件を達成できます。さらに読むためのリンクがいくつかあります。

  1. スレッドの作成 - Task.Factory.StartNew と new Thread() の比較

  2. 長時間実行タスクの作成のベスト プラクティス

  3. タスク レポートの進捗状況

  4. タスク例外の処理

幸運を!

于 2013-05-03T15:00:59.473 に答える
1

いくつかの問題が発生したため、各ウォッチャーを異なるスレッドで実行することにしました。したがって、未処理の例外の場合、そのスレッドのみを停止/強制終了できます

これはスレッドを必要としないように思えます。例外をキャッチする必要があります。なぜあなたはそれをしないのですか?

于 2013-05-03T15:24:46.137 に答える