方法: PLINQ クエリの順序を制御するHow to: Control Ordering in a PLINQ Query

以下の例では、AsOrdered 拡張メソッドを使用して PLINQ クエリの順序を制御する方法を示します。These examples show how to control the ordering in a PLINQ query by using the AsOrdered extension method.

警告

これらの例は使用法を示すことを主な目的としており、同等の LINQ to Objects 順次クエリよりも実行速度が速い場合もあれば遅い場合もあります。These examples are primarily intended to demonstrate usage, and may or may not run faster than the equivalent sequential LINQ to Objects queries.

Example

次の例では、ソース シーケンスの順序を維持します。The following example preserves the ordering of the source sequence. この操作が必要になるのは、たとえば、正確な結果を生成するためにクエリ演算子で順序ありのソース シーケンスが求められる場合です。This is sometimes necessary; for example some query operators require an ordered source sequence to produce correct results.

var source = Enumerable.Range(9, 10000);

// Source is ordered; let's preserve it.
var parallelQuery = from num in source.AsParallel().AsOrdered()
                    where num % 3 == 0
                    select num;

// Use foreach to preserve order at execution time.
foreach (var v in parallelQuery)
    Console.Write("{0} ", v);

// Some operators expect an ordered source sequence.
var lowValues = parallelQuery.Take(10);
Sub OrderedQuery()

    Dim source = Enumerable.Range(9, 10000)

    ' Source is ordered let's preserve it.
    Dim parallelQuery = From num In source.AsParallel().AsOrdered()
                            Where num Mod 3 = 0
                            Select num

    ' Use For Each to preserve order at execution time.
    For Each item In parallelQuery
        Console.Write("{0} ", item)
    Next

    ' Some operators expect an ordered source sequence.
    Dim lowValues = parallelQuery.Take(10)

End Sub

Example

次の例は、ソース シーケンスで順序付けが求められるクエリ演算子を示しています。The following example shows some query operators whose source sequence is probably expected to be ordered. これらの演算子は、順序なしのシーケンスで動作しますが、予測できない結果を生成する場合があります。These operators will work on unordered sequences, but they might produce unexpected results.

// Paste into PLINQDataSample class.
static void SimpleOrdering()
{

    var customers = GetCustomers();

    // Take the first 20, preserving the original order
    var firstTwentyCustomers = customers
                                .AsParallel()
                                .AsOrdered()
                                .Take(20);

    foreach (var c in firstTwentyCustomers)
        Console.Write("{0} ", c.CustomerID);

    // All elements in reverse order.
    var reverseOrder = customers
                        .AsParallel()
                        .AsOrdered()
                        .Reverse();

    foreach (var v in reverseOrder)
        Console.Write("{0} ", v.CustomerID);

    // Get the element at a specified index. 
    var cust = customers.AsParallel()
                        .AsOrdered()
                        .ElementAt(48);

    Console.WriteLine("Element #48 is: {0}", cust.CustomerID);

}
' Paste into PLINQDataSample class
Shared Sub SimpleOrdering()
    Dim customers As List(Of Customer) = GetCustomers().ToList()

    ' Take the first 20, preserving the original order

    Dim firstTwentyCustomers = customers _
                                .AsParallel() _
                                .AsOrdered() _
                                .Take(20)

    Console.WriteLine("Take the first 20 in original order")
    For Each c As Customer In firstTwentyCustomers
        Console.Write(c.CustomerID & " ")
    Next

    ' All elements in reverse order.
    Dim reverseOrder = customers _
                        .AsParallel() _
                        .AsOrdered() _
                        .Reverse()

    Console.WriteLine(vbCrLf & "Take all elements in reverse order")
    For Each c As Customer In reverseOrder
        Console.Write("{0} ", c.CustomerID)
    Next
    ' Get the element at a specified index. 
    Dim cust = customers.AsParallel() _
                        .AsOrdered() _
                        .ElementAt(48)

    Console.WriteLine("Element #48 is: " & cust.CustomerID)

End Sub

このメソッドを実行するには、PLINQ Data Sample プロジェクトの PLINQDataSample クラスに貼り付け、F5 キーを押します。To run this method, paste it into the PLINQDataSample class in the PLINQ Data Sample project and press F5.

Example

次の例は、クエリの最初の部分で順序を維持した後に、join 句のパフォーマンスを向上させるために順序を削除し、最終的な結果に順序を再適用する方法を示しています。The following example shows how to preserve ordering for the first part of a query, then remove the ordering to increase the performance of a join clause, and then reapply ordering to the final result sequence.

// Paste into PLINQDataSample class.
static void OrderedThenUnordered()
{

    var orders = GetOrders();
    var orderDetails = GetOrderDetails();

    var q2 = orders.AsParallel()
       .Where(o => o.OrderDate < DateTime.Parse("07/04/1997"))
       .Select(o => o)
       .OrderBy(o => o.CustomerID) // Preserve original ordering for Take operation.
       .Take(20)
       .AsUnordered()  // Remove ordering constraint to make join faster.
       .Join(
              orderDetails.AsParallel(),
              ord => ord.OrderID,
              od => od.OrderID,
              (ord, od) =>
              new
              {
                  ID = ord.OrderID,
                  Customer = ord.CustomerID,
                  Product = od.ProductID
              }
             )
       .OrderBy(i => i.Product); // Apply new ordering to final result sequence.

    foreach (var v in q2)
        Console.WriteLine("{0} {1} {2}", v.ID, v.Customer, v.Product);

}
' Paste into PLINQDataSample class
Sub OrderedThenUnordered()
    Dim Orders As IEnumerable(Of Order) = GetOrders()
    Dim orderDetails As IEnumerable(Of OrderDetail) = GetOrderDetails()

    ' Sometimes it's easier to create a query
    ' by composing two subqueries
    Dim query1 = From ord In Orders.AsParallel()
             Where ord.OrderDate < DateTime.Parse("07/04/1997")
             Select ord
             Order By ord.CustomerID
             Take 20

    Dim query2 = From ord In query1.AsUnordered()
             Join od In orderDetails.AsParallel() On ord.OrderID Equals od.OrderID
            Order By od.ProductID
            Select New With {ord.OrderID, ord.CustomerID, od.ProductID}


    For Each item In query2
        Console.WriteLine("{0} {1} {2}", item.OrderID, item.CustomerID, item.ProductID)
    Next
End Sub

このメソッドを実行するには、PLINQ Data Sample プロジェクトの PLINQDataSample クラスに貼り付け、F5 キーを押します。To run this method, paste it into the PLINQDataSample class in the PLINQ Data Sample project and press F5.

関連項目See also