0

もともと、私は自分のタスクを実行するためにforeachを使用しています。ただし、作業の効率を上げたいと思います。そこで、Parallel.ForEachを使用してタスクを実行したいと思います。

ただし、「オブジェクト参照がインスタンスに設定されていません」というエラーが発生しました。起こりました。

これが私のコードです:

System.Threading.Tasks.Parallel.ForEach(items, item =>
        {
             System.Threading.Tasks.Parallel.ForEach(item.a, amount =>
                    {
                         WriteToCsv(file, amount.columna, count);
                          count++;
                     });

         });

foreach(アイテム内のvar item)とforeach(item.a内のamount)を使用した場合、コードは正常に機能します。

Parallel.ForEachメソッドで何かが足りませんでしたか?

4

2 に答える 2

8

なぜこれを並行して行う必要があるのですか?ファイルに値を追加していますが、これはシリアル (つまり、非パラレル) プロセスです。

普通foreachに使えば大丈夫です。

于 2012-11-30T08:56:45.283 に答える
0

複数のParallelForeachループをネストしないでください。内側のループは基本的に、外側の並列ループからリソースを盗んでおり、パフォーマンスの向上に優れています。

一度に1つのスレッドだけがファイルに書き込むことができるので、おそらく、内部で使用している機能は、WriteToCsv()データが書き込まれる前にすべてを1つのスレッドにマーシャルバックします。

これを高速化する1つの方法は、並列ループでCSVファイルに追加するテキストを作成し、単一の書き込み操作を使用してそこに追加することです。

var sb = new StringBuilder("");
System.Threading.Tasks.Parallel.ForEach(items, item =>
{
     foreach( var amount in item.a )
     {
         sb.append( GetCsvText(file, amount.columna, count) );
         count++;
     };
});

WriteToCsv( sb.ToString() );

明らかに、CSVファイルに配置されるテキストの順序を制御することはできません。これは、このコードのスレッド間の競合であるためです。サンプルコードについても同じことが言えますが、これは問題ないと思います。

注意:StringBuilderを使用することは、ループで文字列を作成するときのメモリパフォーマンスにとって重要です。

HTH

于 2012-12-12T10:26:26.360 に答える