다음을 통해 공유


PLINQ의 병합 옵션

쿼리가 병렬로 실행되는 경우 PLINQ는 원본 시퀀스를 분할하여 일반적으로 개별 스레드에서 여러 스레드가 서로 다른 부분에서 동시에 작동할 수 있도록 합니다. 예를 들어 Visual Basic의 foreach 루프와 같은 한 스레드에서 결과를 사용하려면, 모든 스레드의 결과를 하나의 시퀀스로 다시 병합해야 합니다. PLINQ에서 수행하는 병합의 종류는 쿼리에 있는 연산자에 따라 달라집니다. 예를 들어 결과에 새 순서를 적용하는 연산자는 모든 스레드의 모든 요소를 버퍼링해야 합니다. 소비 스레드(애플리케이션 사용자의 스레드)의 관점에서 완전히 버퍼링된 쿼리는 첫 번째 결과를 생성하기 전에 눈에 띄는 기간 동안 실행될 수 있습니다. 기본적으로 다른 연산자는 부분적으로 버퍼링됩니다. 결과를 일괄 처리로 생성합니다. 기본적으로 하나의 연산 ForAll 자는 버퍼링되지 않습니다. 모든 스레드의 모든 요소를 즉시 생성합니다.

다음 예제와 같이 메서드를 WithMergeOptions 사용하여 수행할 병합 종류를 나타내는 힌트를 PLINQ에 제공할 수 있습니다.

var scanLines = from n in nums.AsParallel()
                    .WithMergeOptions(ParallelMergeOptions.NotBuffered)
                where n % 2 == 0
                select ExpensiveFunc(n);
Dim scanlines = From n In nums.AsParallel().WithMergeOptions(ParallelMergeOptions.NotBuffered)
                Where n Mod 2 = 0
                Select ExpensiveFunc(n)

전체 예제는 방법: PLINQ에서 병합 옵션 지정을 참조하세요.

특정 쿼리가 요청된 옵션을 지원할 수 없는 경우 옵션은 무시됩니다. 대부분의 경우 PLINQ 쿼리에 대한 병합 옵션을 지정할 필요가 없습니다. 그러나 경우에 따라 쿼리가 기본이 아닌 모드에서 가장 잘 실행되는 테스트 및 측정을 통해 찾을 수 있습니다. 이 옵션의 일반적인 용도는 청크 병합 연산자가 응답성이 뛰어난 사용자 인터페이스를 제공하기 위해 결과를 스트리밍하도록 강제하는 것입니다.

병렬 병합 옵션

열거형에는 ParallelMergeOptions 지원되는 쿼리 셰이프에 대해 결과가 한 스레드에서 사용되는 경우 쿼리의 최종 출력을 생성하는 방법을 지정하는 다음 옵션이 포함됩니다.

  • Not Buffered

    NotBuffered 옵션을 사용하면 각 처리된 요소가 생성되는 즉시 각 스레드에서 반환됩니다. 이 동작은 출력을 "스트리밍"하는 것과 유사합니다. 연산자가 AsOrdered 쿼리 NotBuffered 에 있으면 원본 요소의 순서를 유지합니다. 결과를 사용할 수 있는 즉시 결과를 생성하기 시작하지만 NotBuffered 모든 결과를 생성하는 총 시간은 다른 병합 옵션 중 하나를 사용하는 것보다 더 길 수 있습니다.

  • Auto Buffered

    AutoBuffered 옵션을 사용하면 쿼리가 요소를 버퍼로 수집한 다음 주기적으로 버퍼 콘텐츠를 한 번에 모두 소비 스레드로 생성합니다. 이는 의 "스트리밍" 동작 NotBuffered을 사용하는 대신 원본 데이터를 "청크"로 생성하는 것과 유사합니다. AutoBuffered 사용 중인 스레드에서 첫 번째 요소를 사용할 수 있도록 하는 데 시간이 NotBuffered 오래 걸릴 수 있습니다. 버퍼의 크기와 정확한 생성 동작은 구성할 수 없으며 쿼리와 관련된 다양한 요인에 따라 달라질 수 있습니다.

  • FullyBuffered

    FullyBuffered 옵션을 사용하면 요소가 생성되기 전에 전체 쿼리의 출력이 버퍼링됩니다. 이 옵션을 사용하면 사용 중인 스레드에서 첫 번째 요소를 사용할 수 있기까지 시간이 더 오래 걸릴 수 있지만 전체 결과는 다른 옵션을 사용하는 것보다 더 빠르게 생성될 수 있습니다.

병합 옵션을 지원하는 쿼리 연산자

다음 표에서는 지정된 제한 사항에 따라 모든 병합 옵션 모드를 지원하는 연산자를 나열합니다.

오퍼레이터 제한 사항
AsEnumerable 없음
Cast 없음
Concat 배열 또는 목록 원본만 있는 정렬되지 않은 쿼리입니다.
DefaultIfEmpty 없음
OfType 없음
Reverse 배열 또는 목록 원본만 있는 정렬되지 않은 쿼리입니다.
Select 없음
SelectMany 없음
Skip 없음
Take 없음
Where 없음

다른 모든 PLINQ 쿼리 연산자는 사용자가 제공한 병합 옵션을 무시할 수 있습니다. 예를 들어 ReverseOrderBy일부 쿼리 연산자는 모든 요소가 생성되고 다시 정렬될 때까지 요소를 생성할 수 없습니다. 따라서 ParallelMergeOptions이(가) Reverse과(와) 같은 연산자가 포함된 쿼리에서 사용될 경우, 병합 동작은 그 연산자가 결과를 생성한 후에야 쿼리에 적용됩니다.

병합 옵션을 처리하는 일부 연산자의 기능은 원본 시퀀스의 형식과 쿼리의 앞부분에서 연산자를 AsOrdered 사용했는지 여부에 따라 달라집니다. ForAll 는 항상 NotBuffered 해당 요소를 즉시 생성합니다. OrderBy 은 항상 FullyBuffered입니다. 이는 전체 목록을 정렬한 후 결과를 반환해야 합니다.

참고하십시오