web-dev-qa-db-ja.com

DataTableの並列ForEach

新しいParallel.ForEach関数を使用して、データテーブルをループし、各行でアクションを実行したいと思います。私は以下のコードを変換しようとしています:

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

このコードへ:

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

新しいコードを実行すると、エラーが発生します。

メソッド 'System.Threading.Tasks.Parallel.ForEach(System.Collections.Generic.IEnumerable、System.Action)'の型引数は、使用法から推測できません。型引数を明示的に指定してみてください。

これの正しい構文は何ですか?

49
SchwartzE

_DataTable.Rows_は、DataRowCollectionのみを実装するIEnumerableを返し、_IEnumerable<DataRow>_ではありません。代わりにDataTableDataTableExtensionsから)で AsEnumerable() 拡張メソッドを使用します。

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

これは、System.Data.DataSetExtensionsを参照する必要がないため、受け入れられている回答よりも優れています。

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

ForEachを非ジェネリックコレクションで使用するには、この例に示すように、Cast拡張メソッドを使用してコレクションをジェネリックコレクションに変換できます。

11
Kevin .NET

Parallel.ForEach()は、最初の引数がIEnumerable <>型であることを想定しています。 DataTable.Rowsはそうではありませんが、AsEnumerable()拡張メソッドを使用して1つに変えることができます。試してください:

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

Jon Skeetの答えを修正して、機能させる必要がありました。

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