共用方式為


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;它必須排序整個清單才能輸出。

另請參閱