PLINQ'te Sıra Koruma

PLINQ'ta amaç, doğruluğu korurken performansı en üst düzeye çıkarmaktır. Sorgu mümkün olduğunca hızlı çalışmalı ancak yine de doğru sonuçları üretmelidir. Bazı durumlarda doğruluk, kaynak dizisinin sırasının korunmasını gerektirir; ancak sıralama işlem açısından pahalı olabilir. Bu nedenle, PLINQ varsayılan olarak kaynak dizisinin sırasını korumaz. Bu bağlamda PLINQ, LINQ to SQL'e benzer, ancak sıralamayı koruyan LINQ to Objects'den farklı bir özelliktir.

Varsayılan davranışı geçersiz kılmak için, kaynak dizideki işlecini kullanarak sipariş korumayı AsOrdered açabilirsiniz. Daha sonra sorgunun devamında yöntemini kullanarak sipariş korumasını AsUnordered kapatabilirsiniz. Her iki yöntemle de sorgu, sorgunun paralel mi yoksa sıralı olarak mı yürütüleceğini belirleyen buluşsal yöntemlere göre işlenir. Daha fazla bilgi için bkz . PLINQ'te Hızlandırmayı Anlama.

Aşağıdaki örnek, sonuçları herhangi bir şekilde sıralamaya çalışmadan bir koşulla eşleşen tüm öğeler için filtreleyen sıralanmamış bir paralel sorguyu gösterir.

var cityQuery =
    (from city in cities.AsParallel()
     where city.Population > 10000
     select city).Take(1000);
Dim cityQuery = From city In cities.AsParallel()
                Where city.Population > 10000
                Take (1000)

Bu sorgu, koşula uyan kaynak dizideki ilk 1000 şehri değil, koşulu karşılayan 1000 şehirden oluşan bir küme oluşturmak zorunda değildir. PLINQ sorgu işleçleri, kaynak diziyi eşzamanlı görev olarak işlenen birden çok alt diziye böler. Sıra koruma belirtilmezse, her bölümden alınan sonuçlar rastgele bir sırada sorgunun bir sonraki aşamasına teslim edilir. Ayrıca, bir bölüm kalan öğeleri işlemeye devam etmeden önce sonuçlarının bir alt kümesini verebilir. Sonuçta elde edilen sıra her seferinde farklı olabilir. İşletim sisteminin iş parçacıklarını nasıl zamanladığına bağlı olduğundan uygulamanız bunu denetleyemiyor.

Aşağıdaki örnek, kaynak dizideki işlecini AsOrdered kullanarak varsayılan davranışı geçersiz kılar. Bu, yöntemin Take , koşulu karşılayan kaynak dizideki ilk 1000 şehri döndürmesini sağlar.

var orderedCities =
    (from city in cities.AsParallel().AsOrdered()
     where city.Population > 10000
     select city).Take(1000);

Dim orderedCities = From city In cities.AsParallel().AsOrdered()
                    Where city.Population > 10000
                    Take (1000)

Ancak, bölümler boyunca özgün sıralamayı izlemesi ve birleştirme sırasında sıralamanın tutarlı olduğundan emin olması gerektiğinden, bu sorgu büyük olasılıkla sıralanmamış sürüm kadar hızlı çalışmaz. Bu nedenle, yalnızca gerekli olduğunda ve yalnızca sorgunun gerektiren bölümleri için kullanmanızı AsOrdered öneririz. Sipariş koruması artık gerekli olmadığında, kapatmak için kullanın AsUnordered . Aşağıdaki örnek, iki sorgu oluşturarak bunu başarıyor.

var orderedCities2 =
    (from city in cities.AsParallel().AsOrdered()
     where city.Population > 10000
     select city).Take(1000);

var finalResult =
    from city in orderedCities2.AsUnordered()
    join p in people.AsParallel()
    on city.Name equals p.CityName into details
    from c in details
    select new
    {
        city.Name,
        Pop = city.Population,
        c.Mayor
    };

foreach (var city in finalResult) { /*...*/ }
Dim orderedCities2 = From city In cities.AsParallel().AsOrdered()
                     Where city.Population > 10000
                     Select city
                     Take (1000)

Dim finalResult = From city In orderedCities2.AsUnordered()
                  Join p In people.AsParallel() On city.Name Equals p.CityName
                  Select New With {.Name = city.Name, .Pop = city.Population, .Mayor = city.Mayor}

For Each city In finalResult
    Console.WriteLine(city.Name & ":" & city.Pop & ":" & city.Mayor)
Next

PLINQ'un sorgunun geri kalanı için order-imposing işleçleri tarafından üretilen bir sıranın sıralamasını koruduğuna dikkat edin. Başka bir AsOrdereddeyişle ve ThenBy gibi OrderBy işleçler, çağrısı tarafından takip edilmiş gibi değerlendirilir.

Sorgu İşleçleri ve Sıralama

Aşağıdaki sorgu işleçleri, sorgudaki sonraki tüm işlemlere veya çağrılana kadar AsUnordered sipariş korumasını tanıtır:

Aşağıdaki PLINQ sorgu işleçleri bazı durumlarda doğru sonuçlar üretmek için sıralı kaynak dizileri gerektirebilir:

Bazı PLINQ sorgu işleçleri, kaynak sıralarının sıralı veya sırasız olmasına bağlı olarak farklı davranır. Aşağıdaki tabloda bu işleçler listelenmiştir.

Operatör Kaynak dizisi sıralandığında elde edilen sonuç Kaynak dizisi sıralanmadığında elde edilen sonuç
Aggregate İlişkisiz veya ticari olmayan işlemler için belirsiz çıkış İlişkisiz veya ticari olmayan işlemler için belirsiz çıkış
All Uygulanamaz Uygulanamaz
Any Uygulanamaz Uygulanamaz
AsEnumerable Uygulanamaz Uygulanamaz
Average İlişkisiz veya ticari olmayan işlemler için belirsiz çıkış İlişkisiz veya ticari olmayan işlemler için belirsiz çıkış
Cast Sıralı sonuçlar Sıralanmamış sonuçlar
Concat Sıralı sonuçlar Sıralanmamış sonuçlar
Count Uygulanamaz Uygulanamaz
DefaultIfEmpty Uygulanamaz Uygulanamaz
Distinct Sıralı sonuçlar Sıralanmamış sonuçlar
ElementAt Belirtilen öğeyi döndür Rastgele öğe
ElementAtOrDefault Belirtilen öğeyi döndür Rastgele öğe
Except Sıralanmamış sonuçlar Sıralanmamış sonuçlar
First Belirtilen öğeyi döndür Rastgele öğe
FirstOrDefault Belirtilen öğeyi döndür Rastgele öğe
ForAll Paralel olarak belirsiz bir şekilde yürütür Paralel olarak belirsiz bir şekilde yürütür
GroupBy Sıralı sonuçlar Sıralanmamış sonuçlar
GroupJoin Sıralı sonuçlar Sıralanmamış sonuçlar
Intersect Sıralı sonuçlar Sıralanmamış sonuçlar
Join Sıralı sonuçlar Sıralanmamış sonuçlar
Last Belirtilen öğeyi döndür Rastgele öğe
LastOrDefault Belirtilen öğeyi döndür Rastgele öğe
LongCount Uygulanamaz Uygulanamaz
Min Uygulanamaz Uygulanamaz
OrderBy Sırayı yeniden sıralar Yeni sıralı bölümü başlatır
OrderByDescending Sırayı yeniden sıralar Yeni sıralı bölümü başlatır
Range Geçerli değil (ile aynı varsayılan AsParallel ) Uygulanamaz
Repeat Geçerli değil (ile aynı varsayılan AsParallel) Uygulanamaz
Reverse Ters -ine çevirir Hiçbir şey yapılmaz
Select Sıralı sonuçlar Sıralanmamış sonuçlar
Select (dizine alınan) Sıralı sonuçlar Sıralanmamış sonuçlar.
SelectMany Sıralı sonuçlar. Sıralanmamış sonuçlar
SelectMany (dizine alınan) Sıralı sonuçlar. Sıralanmamış sonuçlar.
SequenceEqual Sıralı karşılaştırma Sıralanmamış karşılaştırma
Single Uygulanamaz Uygulanamaz
SingleOrDefault Uygulanamaz Uygulanamaz
Skip İlk n öğeyi atlar Herhangi bir n öğeyi atlar
SkipWhile Sıralı sonuçlar. Nondeterministic. Geçerli rastgele sırada SkipWhile gerçekleştirir
Sum İlişkisiz veya ticari olmayan işlemler için belirsiz çıkış İlişkisiz veya ticari olmayan işlemler için belirsiz çıkış
Take İlk n öğeleri alır Herhangi bir n öğeyi alır
TakeWhile Sıralı sonuçlar Nondeterministic. Geçerli rastgele sırada TakeWhile gerçekleştirir
ThenBy Takviye -leri OrderBy Takviye -leri OrderBy
ThenByDescending Takviye -leri OrderBy Takviye -leri OrderBy
ToArray Sıralı sonuçlar Sıralanmamış sonuçlar
ToDictionary Uygulanamaz Uygulanamaz
ToList Sıralı sonuçlar Sıralanmamış sonuçlar
ToLookup Sıralı sonuçlar Sıralanmamış sonuçlar
Union Sıralı sonuçlar Sıralanmamış sonuçlar
Where Sıralı sonuçlar Sıralanmamış sonuçlar
Where (dizine alınan) Sıralı sonuçlar Sıralanmamış sonuçlar
Zip Sıralı sonuçlar Sıralanmamış sonuçlar

Sıralanmamış sonuçlar etkin olarak karıştırılmaz; yalnızca kendilerine herhangi bir özel sıralama mantığı uygulanmaz. Bazı durumlarda, sıralanmamış bir sorgu kaynak dizinin sırasını koruyabilir. Dizine alınan Select işlecini kullanan sorgular için PLINQ, çıkış öğelerinin artan dizin sırasına göre çıkarılacağını garanti eder, ancak hangi dizinlerin hangi öğelere atanacağı konusunda hiçbir garanti vermemektedir.

Ayrıca bkz.