2016-09-12 4 views
4

Im folgenden Code scheint nur jedes zweite Element des Arrays aufgefüllt zu werden. Warum?Parallel.For das Überspringen von Elementen

Random rand = new Random(); 
int byteLength = 10000000; 
var result = new byte[10][]; 
Parallel.For(0, 10, (i) => 
{ 
    int length = rand.Next(byteLength); 
    var tempResult = new byte[length]; 
    Thread.Sleep(100); 
    rand.NextBytes(tempResult); 
    result[i] = tempResult; 
}); 

Gegensatz dazu (nicht parallel) Code, der jedes Element füllt:

rand = new Random(); 
var result2 = new byte[10][]; 
for (int i = 0; i < 10; i++) 
{ 
    int length = rand.Next(byteLength); 
    var tempResult = new byte[length]; 
    Thread.Sleep(100); 
    rand.NextBytes(tempResult); 
    result2[i] = tempResult; 
} 

bei MSDN in der Dokumentation zu the examples Vergleicht man vermuten I ist dies, weil result außerhalb des Parallel.For delegieren ist - Somit haben die Threads Probleme beim Zugriff auf result. Aber als Neuling im Multithreading bin ich mir nicht sicher, ob das der Fall ist.

+4

Sie verwenden eine einzelne Instanz von 'Random' aus mehreren Threads. Das ist eine schlechte Idee - "System.Random" ist nicht Thread-sicher. Es sollte aber immer noch jedes Element bevölkern ... was genau siehst du? Nullreferenzen oder nur Einträge, bei denen alle Bytes 0 sind? –

+3

System.Random ist nicht Thread-sicher. –

+0

Vielen Dank für den Hinweis auf System.Random. Das Ändern, so dass Instanzen innerhalb des Delegaten erstellt werden, scheint das Problem zu beheben. Möchte jemand als Antwort schreiben, und ich werde als beantwortet markieren? –

Antwort

1

Obwohl Random nicht threadsicher ist (wie von anderen Postern zu Ihrer Frage kommentiert), bleibt die Frage, warum Sie unbestückte Daten sehen, da die Iterationsvariable i nicht vom Wert der Randoms-Rückgabe abhängig ist. In diesem Fall glaube ich, dass Random Null zurückliefert, wenn es in einer ungeschützten Weise aufgerufen wird, was zu dem Schluss führte, dass die Daten nicht gefüllt waren, aber Sie hatten gerade ein leeres Array. Dies kann getestet werden, indem Sie zunächst ein nicht leeres Array zuweisen und sehen, ob Ihre Routine es auf eine Länge von Null ändert. Ich denke, das ist die vollständige Antwort auf "Warum?"

Verwandte Themen