0

OK 別のアプリによって作成されたファイルに基づいていくつかのコントラクトを生成するアプリケーションがあります。

作成中のファイルを監視するファイルウォッチャーを実装しbackgroundworker、ファイル名に基づいてコントラクトを作成するプロセスを開始します。

私が抱えている問題は、バックグラウンドワーカープロセス中EnableRaisingEventsにfalseに設定して、最初のコントラクトが実行されている間にアプリが別のコントラクトセットの処理を開始しないようにすることです(実行中にバックグラウンドワーカーの呼び出しを停止することでもあります)一度に 2 つのことを実行することはできません!)。

すべて正常に動作し、他のアプリがファイルを作成し、filewatcher がそれを取得して処理を開始します。問題は、処理が終了すると filewatcher が再度有効になることですが、EnableRaisingEventsfalse のときに作成されたファイルは取得されないと思います。そのため、コントラクトを生成するための初期ファイルを作成するアプリケーションが、アプリの処理中に別のファイルを作成した場合、それはそのまま残されます。それは理にかなっていますか?そして、これを回避する最善の方法は何ですか?

最初のコントラクトの作成が完了したら、filewatcher が無効になっている間に作成された他のファイルをディレクトリで探し、ファイルウォッチャーがない場合は filewatcher を再度有効にするという別のプロセスを用意することを考えていましたが、疑問に思っていますこれを行う簡単な方法があれば?

4

2 に答える 2

0

プロセスをタスクに分割できます。1 つのタスクは FileRegistrator で、新しいファイルを取得してデータベースに登録します。EnableRaisingEvents を false にする必要はありません。

次のタスクは、データベースにクエリを実行し、最初のタスクを見つけて処理する ProcessorTask (または任意の名前) です。定期的にデータベースにクエリを実行して、新しいファイルが登録されているかどうかを確認します。

Windows サービスで Quartz.NET スケジューラを使用して、この小さなプロセッサを実装できます。

(私も少し前にほぼ同じことをしましたが、FileSystemWatcher は使用しませんでした)

于 2013-04-10T12:02:59.740 に答える
0

BlockingCollection がこれを行います。
FileWatcher をホットに保ち、ブロッキング コレクションに追加します。
コンシューマーは、コレクションを一度に 1 つずつ処理します。

BlockingCollection クラス

class AddTakeDemo
{
    // Demonstrates: 
    //      BlockingCollection<T>.Add() 
    //      BlockingCollection<T>.Take() 
    //      BlockingCollection<T>.CompleteAdding() 
    public static void BC_AddTakeCompleteAdding()
    {
        // here you need to synch as it would have missed any 
        // new files while the application was down 
        // yes L-Three and any files that were not yet processed 
        // clearly the existing program is an end to end synch 
        // or no synch at all as it could be nothing else 
        using (BlockingCollection<int> bc = new BlockingCollection<int>())
        {

            // Spin up a Task to populate the BlockingCollection  
            using (Task t1 = Task.Factory.StartNew(() =>
            {
                //  FielSystem watcher                    
                bc.Add(fille);

            }))
            {

                // Spin up a Task to consume the BlockingCollection 
                using (Task t2 = Task.Factory.StartNew(() =>
                {
                    try
                    {
                        // Consume consume the BlockingCollection 
                        while (true) Console.WriteLine(bc.Take());
                        // process the file
                    }
                    catch (InvalidOperationException)
                    {
                        // An InvalidOperationException means that Take() was called on a completed collection
                        Console.WriteLine("That's All!");
                    }
                }))

                    Task.WaitAll(t1, t2);
            }
        }
    }
}
于 2013-04-10T13:12:00.390 に答える