web-dev-qa-db-fra.com

Parallel ForEach sur DataTable

Je voudrais utiliser la nouvelle fonction Parallel.ForEach pour parcourir une table de données et effectuer des actions sur chaque ligne. J'essaie de convertir le code ci-dessous:

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

Vers ce code:

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

Lorsque j'exécute le nouveau code, j'obtiens l'erreur:

Les arguments de type pour la méthode 'System.Threading.Tasks.Parallel.ForEach (System.Collections.Generic.IEnumerable, System.Action)' ne peuvent pas être déduits de l'utilisation. Essayez de spécifier explicitement les arguments de type.

Quelle est la syntaxe correcte pour cela?

49
SchwartzE

DataTable.Rows Renvoie un DataRowCollection qui implémente uniquement IEnumerable, pas IEnumerable<DataRow>. Utilisez plutôt la méthode d'extension AsEnumerable() sur DataTable (à partir de DataTableExtensions):

Parallel.ForEach(dt.AsEnumerable(), drow =>
{
    ...
    Do Stuff
    ...
});
103
Jon Skeet

C'est mieux que la réponse acceptée car cela n'a pas besoin de référencer System.Data.DataSetExtensions:

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

Pour utiliser ForEach avec une collection non générique, vous pouvez utiliser la méthode d'extension Cast pour convertir la collection en une collection générique, comme indiqué dans cet exemple.

11
Kevin .NET

Parallel.ForEach () s'attend à ce que le premier argument soit un type IEnumerable <>. DataTable.Rows ne l'est pas, mais vous pouvez le transformer en un seul avec la méthode d'extension AsEnumerable (). Essayer:

... Parallel.ForEach(dt.AsEnumerable(), drow => ...
8
JaredReisinger

J'ai dû modifier la réponse de Jon Skeet pour que ça marche.

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