2015-07-10 11 views
5

Sto cercando di determinare come AsParallel() divide è 'fonte', e in effetti ciò che si intende per 'fonte' ...In che modo AsParallel() si divide in "sorgente"?

Per esempio ...

public class CSVItem 
{ 
    public DateTime Date { get; set; } 
    public string AccountNumber { get; set; } 
} 

List<CSVItem> CSVItemList = new List<CSVItem>(); 

Poi mise 500k variabile CSVItem in CSVItemList.

usare:

CSVItemList = CSVItemList.AsParallel().OrderBy(x => x.AccountNumber).ThenBy(q => q.Date).ToList(); 

Sarà solo dividere la 'sorgente' (cioè per esempio 250k record su ciascuno dei due fili) su più fili asynch ed eseguire l'OrderBy() ThenBy() su ciascuno. thread quindi unisci i risultati ...

Oppure separerà OrderBy() e ThenBy() in thread separati ed eseguirli e quindi unire i risultati ... dando una lista stranamente ordinata?

+0

[questo] (http://download.microsoft.com/download/B/C/F/BCFD4868-1354-45E3-B71B-B851CD78733D/WhenToUseParallelForEachOrPLINQ.pdf) potrebbe contenere le risposte alla tua domanda (in basso pagina 5). L'ho trovato nella [risposta] (http://stackoverflow.com/questions/3789998/parallel-foreach-vs-foreachienumerablet-asparallel) di un'altra domanda –

risposta

4

E Gose uno per uno a) fatto con OrderBy risultato di fusione e di Gose per b) ThenBy. Sotto forma di immagine Albahari blog mostra come funziona cioè ci vuole uno per uno

enter image description here

D: quanti numero di compito

A: si può decidere questo utilizzando WithDegreeOfParallelism forza PLINQ a eseguire simultaneamente il numero specificato di compiti

//create 5 task 
    List.AsParallel().WithDegreeOfParallelism(5) 

Verificare: Parallel Programming

+0

Sei sicuro? In generale, MSDN implica che è un po 'più confuso di così ... "La query divide l'origine in attività eseguite in modo asincrono su più thread.L'ordine in cui ogni attività viene completata dipende non solo dalla quantità di lavoro necessaria per elaborare gli elementi nella partizione, ma anche su fattori esterni come il modo in cui il sistema operativo pianifica ciascun thread. " Vedere https://msdn.microsoft.com/en-us/library/dd460714%28v=vs.110%29.aspx –

+2

@PaulZahra - io uso questo come ref http://www.albahari.com/threading/part5 .aspx quando si tratta di paralleli linq –

2

Ho creato un piccolo esempio per verificare, quale è vero.

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Program 
{ 
    static void Main(string[] args) 
    { 
     List<TestItem> items = new List<TestItem>(); 
     List<TestItem> itemsNonParallel = new List<TestItem>(); 

     items.Add(new TestItem() { Age = 1, Size = 12 }); 
     items.Add(new TestItem() { Age = 2, Size = 1 }); 
     items.Add(new TestItem() { Age = 5, Size = 155 }); 
     items.Add(new TestItem() { Age = 23, Size = 42 }); 
     items.Add(new TestItem() { Age = 7, Size = 32 }); 
     items.Add(new TestItem() { Age = 9, Size = 22 }); 
     items.Add(new TestItem() { Age = 34, Size = 11 }); 
     items.Add(new TestItem() { Age = 56, Size = 142 }); 
     items.Add(new TestItem() { Age = 300, Size = 13 }); 

     itemsNonParallel.Add(new TestItem() { Age = 1, Size = 12 }); 
     itemsNonParallel.Add(new TestItem() { Age = 2, Size = 1 }); 
     itemsNonParallel.Add(new TestItem() { Age = 5, Size = 155 }); 
     itemsNonParallel.Add(new TestItem() { Age = 23, Size = 42 }); 
     itemsNonParallel.Add(new TestItem() { Age = 7, Size = 32 }); 
     itemsNonParallel.Add(new TestItem() { Age = 9, Size = 22 }); 
     itemsNonParallel.Add(new TestItem() { Age = 34, Size = 11 }); 
     itemsNonParallel.Add(new TestItem() { Age = 56, Size = 142 }); 
     itemsNonParallel.Add(new TestItem() { Age = 300, Size = 13 }); 

     foreach (var item in items.AsParallel().OrderBy(x => x.Age).ThenBy(x => x.Size)) 
     { 
      Console.WriteLine($"Age: {item.Age}  Size: {item.Size}"); 
     } 

     Console.WriteLine("---------------------------"); 

     foreach (var item in itemsNonParallel.OrderBy(x => x.Age).ThenBy(x => x.Size)) 
     { 
      Console.WriteLine($"Age: {item.Age}  Size: {item.Size}"); 
     } 

     Console.ReadLine();   
    } 
} 

public class TestItem 
{ 
    public int Age { get; set; } 
    public int Size { get; set; } 
} 

Risultato

AsParallel() fa quello che vogliamo. Elabora dapprima OrderBy() parallelo, fonde indietro l'elenco e quindi passa alla query successiva, nel nostro caso ThenBy().

+0

Un confronto di elenchi sarebbe utile .... non sicuro list1.Except (list2) è corretto per questo però ... come vogliamo controllare l'ordine e non il contenuto ...allora potremmo eseguire il codice contro liste umbre e confrontare facilmente. –

+0

Hmm vedi il violino qui ... Sequenza uguale dando false ... anche se le liste sembrano uguali ... https://dotnetfiddle.net/KLOY1W –

+1

@PaulZahra: 'SequenceEqual' restituisce false perché quando due oggetti vengono controllati per l'uguaglianza, per impostazione predefinita passa se fanno riferimento allo stesso oggetto. La soluzione facile è quella di memorizzare gli stessi oggetti in entrambi gli elenchi sostituendo il codice per aggiungere un gruppo di TestItem a 'itemsNonParallel' con' itemsNonParallel = items.ToList(); '. –