2010-08-04 11 views
42

Ich möchte die neue Parallel.ForEach-Funktion verwenden, um eine Datentabelle durchzulaufen und Aktionen für jede Zeile auszuführen. Ich versuche, den Code zu konvertieren:Parallel ForEach on DataTable

 foreach(DataRow drow in dt.Rows) 
     { 
      ... 
      Do Stuff 
      ... 
     } 

Zu diesem Code:

 System.Threading.Tasks.Parallel.ForEach(dt.Rows, drow => 
       { 
        ... 
        Do Stuff 
        ... 
       }); 

Wenn ich den neuen Code ausführen bekomme ich den Fehler:

Die Art Argumente für die Methode ‚System .Threading.Tasks.Parallel.ForEach (System.Collections.Generic.IEnumerable, System.Action) kann nicht aus der Verwendung abgeleitet werden. Versuchen Sie, die Typargumente explizit anzugeben.

Was ist die korrekte Syntax dafür?

Antwort

89

DataTable.Rows gibt eine DataRowCollection zurück, die nur IEnumerable, nicht IEnumerable<DataRow> implementiert. Verwenden Sie die AsEnumerable() Erweiterungsmethode auf DataTable (von DataTableExtensions) statt:

Parallel.ForEach(dt.AsEnumerable(), drow => 
{ 
    ... 
    Do Stuff 
    ... 
}); 
+2

D'oh! Schlag auf den Schlag (um Sekunden)! – JaredReisinger

+0

wäre diese Erweiterung für andere Sammlungen verfügbar, die IEnumerable implementieren? wie die TreeNodeCollection? oder müsste ich diese Erweiterung selbst erstellen? –

+0

@Scott: Sie müssten es selbst schreiben - weil es sonst nicht wissen wird, welche Art von IEnumerable zurückgeben soll, wenn Sie sehen, was ich meine. –

7

Parallel.ForEach() erwartet das erste Argument ein IEnumerable <> Typ zu sein. DataTable.Rows ist nicht, aber Sie können es mit der Erweiterungsmethode AsEnumerable() in eins verwandeln. Versuchen:

... Parallel.ForEach(dt.AsEnumerable(), drow => ... 
6

Das ist besser als die akzeptierte Antwort, weil diese nicht referenzieren System.Data.DataSetExtensions benötigt:

Parallel.ForEach(dt.Rows.Cast<DataRow>(), dr => 

Um FürJeden mit einer nicht-generischen Auflistung zu verwenden, können Sie die Umwandeln der Auflistung in eine generische Auflistung, wie in diesem Beispiel gezeigt.

+1

Aber bedenken Sie dies , von [Darsteller] (https://msdn.microsoft.com/en-us/library/bb341406 (v = vs.110) .aspx): "Wenn ein Element nicht zum Eingeben von TResult umgewandelt werden kann, wird diese Methode ausgelöst Eine Ausnahme: Um nur die Elemente zu erhalten, die in TResult umgewandelt werden können, verwenden Sie die OfType-Methode anstelle von Cast (IEnumerable). " – ALEXintlsos

0

Ich musste Jon Skeets Antwort ändern, damit es funktioniert.

Parallel.ForEach(dt.AsEnumerable<DataRowType>(), drow => { 
    drow.SomeCol = ""; 
});