4

並列処理が.Netでどのように実装されているかを理解しようとしています。次のコードは、 ReedCopseyBlogの例です。

このコードは顧客コレクションをループし、最後の連絡から14日後に電子メールを送信します。ここでの私の質問は、顧客テーブルが非常に大きく、電子メールの送信に数秒かかる場合、このコードは他の重要なプロセスにサービス拒否モードのCPUを使用しませんか?

次のコード行を並行して実行する方法はありますが、他のプロセスがCPUを共有できるように、少数のコアのみを使用しますか?または私は間違った方法で問題に取り組んでいますか?

Parallel.ForEach(customers, (customer, parallelLoopState) =>
{
    // database operation
    DateTime lastContact = theStore.GetLastContact(customer); 
    TimeSpan timeSinceContact = DateTime.Now - lastContact;

    // If it's been more than two weeks, send an email, and update...
    if (timeSinceContact.Days > 14)
    {
         // Exit gracefully if we fail to email, since this 
         // entire process can be repeated later without issue.
         if (theStore.EmailCustomer(customer) == false)
             parallelLoopState.Break();
         else
             customer.LastEmailContact = DateTime.Now;
    }
});

受け入れられた回答:

思考プロセスは正しかった!Cole Campbellが指摘したように、この特定の例でParallelOptionオブジェクトを指定することにより、使用するコアの数を制御および構成できます。方法は次のとおりです。

var parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 
                 Math.Max(Environment.ProcessorCount / 2, 1);

また、Parallel.ForEachは次のように使用されます。

Parallel.ForEach(customers, parallelOptions, 
                                (customer, parallelLoopState) =>
{
    //do all same stuff
}

.WithDegreeOfParallelism(int numberOfThreads)を使用して、同じ概念をPLINQに適用できます。並列オプションの構成方法の詳細については、こちらをお読みください。

4

1 に答える 1

8

タスク並列処理ライブラリは、実行するタスクをスケジュールするときにシステムワークロードを考慮に入れるように設計されているため、これは問題にはなりません。ただし、本当に必要な場合は、のオーバーロードの1つに渡すことができるクラスのMaxDegreeOfParallelismプロパティを使用して、実行できる同時操作の数を制限できます。ParallelOptionsForEach()

于 2012-05-15T02:27:13.993 に答える