다음을 통해 공유


방법: PLINQ 쿼리에서 순서 제어

다음 예제에서는 확장 메서드를 사용하여 PLINQ 쿼리에서 순서를 제어하는 AsOrdered 방법을 보여 줍니다.

경고

이러한 예제는 주로 사용량을 보여주기 위한 것이며 해당 순차 LINQ to Objects 쿼리보다 더 빠르게 실행되거나 실행되지 않을 수 있습니다.

예제 1

다음 예제에서는 소스 시퀀스의 순서를 유지합니다. 이 작업은 때때로 필요합니다. 예를 들어 일부 쿼리 연산자는 올바른 결과를 생성하기 위해 순서가 지정된 소스 시퀀스가 필요합니다.

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 item in parallelQuery)
{
    Console.Write($"{item} ");
}

// 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

예제 2

다음 예제에서는 원본 시퀀스가 순서가 지정될 것으로 예상되는 일부 쿼리 연산자를 보여줍니다. 이러한 연산자는 순서가 지정되지 않은 시퀀스에서 작동하지만 예기치 않은 결과를 생성할 수 있습니다.

// 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: {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 데이터 샘플 프로젝트의 PLINQDataSample 클래스에 붙여넣고 F5 키를 누릅니다.

예제 3

다음 예제에서는 쿼리의 첫 번째 부분에 대한 순서를 유지한 다음, 조인 절의 성능을 높이기 위해 순서를 제거한 다음 최종 결과 시퀀스에 순서를 다시 적용하는 방법을 보여 줍니다.

// 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($"{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 데이터 샘플 프로젝트의 PLINQDataSample 클래스에 붙여넣고 F5 키를 누릅니다.

참고하십시오