1

私は現在、.net 4.0 と winforms を使用して小さなサーバー関連のアプリケーションを構築しています。タスク並列ライブラリの利点を利用したいのですが、ここでの最良または「正しい」実装について少し迷っています。

目的:

  1. 正規表現パターンを使用してネットワーク パスからファイルを消費する (15 分ごとに消費する)
  2. ファイルの読み取り (csv スタイル)
  3. 一部の列をスキップするようにファイルを書き換える
  4. 一括挿入または更新によってファイル データを SQL Server に転送する

次のようなカスケード アプローチを考えています。

ProducerConsumerTask1 (ネットワーク パスからファイルを取得する/ファイルを読み取り可能にする)
ProducerConsumerTask2 (Task1 からファイルを読み取る/Task1 からファイルを書き換える)
ProducerConsumerTask3 (書き換えられたファイルを取得する/Task2 から DB にファイルを転送する)

そして少しのコード:

private static BlockingCollection<ManagedFile> searchQueue = new BlockingCollection<ManagedFile>(limit);
private const int limit = 100;

public void StartFileTask()
{
    Task[] producers = new Task[1];
    producers[0] = Task.Factory.StartNew(() => ProduceFileSearchTask());


    Task.Factory.StartNew(() => ConsumeFileSearchTask());
}

public static void ProduceFileSearchTask()
{
    var pattern = new Regex(Properties.Settings.Default.DefaultRegexPattern);
    string path = Properties.Settings.Default.DefaultImportPath;

    IEnumerable<FileInfo> files = new DirectoryInfo(path)
                                        .EnumerateFiles("*.*", SearchOption.AllDirectories)
                                        .Where(x => pattern.IsMatch(x.Name));

    for (int i = 0; i < files.ToList().Count(); i++)
    {
        ManagedFile _managedFile = new ManagedFile();
        _managedFile.Id = Guid.NewGuid();
        _managedFile.ManagedFileName = files.ElementAt(i).FullName;
        _managedFile.ManagedFileAddedOn = DateTime.Now;

        if (!searchQueue.IsAddingCompleted)
            searchQueue.Add(_managedFile);

        Thread.SpinWait(100000); 
    }           
}

public static void ConsumeFileSearchTask()
{
    foreach (var item in searchQueue.GetConsumingEnumerable())
    {
        // use ProducerTask for Reading the Files here
    }
}

誰かがこのアイデアについて彼の考えを共有してくれたらうれしいです. これは対処する良い方法ですか?この場合、何が良いでしょうか?この場合の別のトピック: UI 自動化/レポート/UI へのステータス更新はどうですか? これはどのように行うことができますか?イベント/デリゲートですね。

ありがとう!

4

1 に答える 1

1

答えとして私のコメントを追加する:)

これは、Tasks.Dataflowを使用するのに最適なシナリオのように見えます。これをチェックしてください、それはあなたに大いに役立つかもしれません:Tasks.DataFlowホワイトペーパー

別の推奨されるアプローチ:1つのタスクが新しいファイルを読み取り、それらの一部をBlockingCollection(別名Producer-Consumer)に配置します。コンシューマータスクは、並行タスクのリストを維持し、コレクションから読み取り、新しいタスクをスケジュールします。コンシューマータスクとそれが同時に追跡できるファイルの数を微調整することで、パフォーマンスを確認できます。あるタスクが終了したという通知をコンシューマーが受け取ったら、プロデューサーから再度読み取り、別のタスクをスケジュールします。それらは独立して並列になります。

注目すべきもう1つのフレームワークは、Reactive Extensionsであり、ソースを監視可能なファイルのコレクションに変換し、そこでスロットリングを適用します。

于 2012-08-27T15:21:07.283 に答える