3

誰かがこれを知っていると確信しており、答えにとても感謝しています。デリゲートや非同期などについてはよく知らないので、実装方法の一般的な例を教えてください。

Parallel.Foreach を使用して多くの異なるファイルのメソッドを同時に実行できるワークフローがあります (スイート、そのプロセッサを粉砕します) - ただし、そのメソッドが終了した後、別のメソッドを実行する必要があります (以前のレポートに関するレポートを生成します)。この 2 番目の方法は並行して実行できません。

レポートを生成する前に、Parallel.ForEach 内のすべてのファイルが完了するのを待ちたくありません (これは必要ありません)。しかし、最初のメソッドが終了したときにレポート生成メソッドを開始すると、問題が発生します。ある種のキューか何かがありますか?それを行うためのかなりの方法があるはずですよね?

ありがとう

4

5 に答える 5

2

ジムGの意味は次のとおりです。

var lockObj = new object();

Parallel.Foreach(files, file => 
{
    // Processing file
    lock(lockObj)
    {
        // Generate report.
    }
});
于 2012-09-07T19:17:31.670 に答える
1

2 番目のメソッドは、継続タスクとしてチェーンする必要があります。

2 番目の方法では、lockまたはミューテックスを使用して、並行して実行されないようにします。

于 2012-09-07T19:05:29.453 に答える
1

もう 1 つのオプションは、生産者と消費者のモデルを使用することです。完成したデータを入れるスレッド セーフなブロッキング コレクションがあり、そのコレクションからデータを取得するレポートを実行する 1 つのスレッドがあります。

//Collection to hold the data the processed files generated
var proccesedDataItems = new new BlockingCollection<ResultData>();

//A thread that processes the files
var processReports = new Task(() =>
{
    //Removes items from the collection, if the collection is empty it blocks
    // or if "CompletedAdded" has been called it will reach the "end" of the 
    // collection
    foreach(var processedData in proccesedDataItems.GetConsumingEnumerable())
    {
        BuildReport(processedData);
    }
});
processReports.Start();    

//Generating the data
Parallel.Foreach(files, file => 
{
   var proccesedData = ProcessFile(file)
   proccesedDataItems.Add(processedData);
});

//Let anyone consuming the collection that you can stop waiting for new items.
proccesedDataItems.CompleteAdding();
于 2012-09-07T19:54:39.987 に答える
1

Concurrency and Coordination Runtime (CCR)のArbiter.Interleave調整プリミティブは、必要な機能を実現する簡単な方法を提供します。基本的に、並行タスク用に 1 つ、排他的タスク (並行して実行されない) 用に 1 つ、プロセス全体のシャットダウン用に 1 つの 3 つの受信者グループを渡します。ここで使用方法の例を見つけることができます

于 2012-09-07T19:26:14.527 に答える
1

このようなことは、TPL データフローのモデルにうまく適合します。ファイルを処理する 1 つの並列ブロックを作成してから、レポートを生成する別の非並列ブロックを作成します。

var processFileBlock = new TransformBlock<File, Result>(
    file => ProcessFile(file),
    new ExecutionDataflowBlockOptions
    {
        MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
    });

var generateReportBlock = new ActionBlock<Result>(
    result => GenerateReport(result));

processFileBlock.LinkTo(generateReportBlock);

foreach (var file in files)
    processFileBlock.Post(file);

すべての処理が完了するまで待ちたい場合は、 と を使用してコードを追加する必要がありComplete()ますCompletetion

于 2012-09-08T00:07:12.427 に答える