2017-02-03 6 views
0

私は複数のプロセッサを搭載したマシン上で動作するアプリケーションを持っています。開発マシンのVisual Studioでコードを実行すると、かなり速く実行されます。同じ入力を持つサーバー上で公開されたバージョンを実行すると、実行速度が低下します。私はここで理論に取り組んでいます。私の開発ラップトップは、サーバー上の複数のプロセッサよりも高いクロック速度を持つ単一のプロセッサを備えています。アプリケーションはシングルスレッドなので、ローカルで高速に実行されることは論理的です。したがって、サーバーに追加のプロセッサーを使用するためにアプリケーションにマルチスレッドを追加できれば、パフォーマンスを向上させることができます。それはとにかく理論です。マルチスレッドアプリケーションでの私の経験は限られています。スレッドセーフティ(Paralel.For)

アプリケーションの要点は、いくつかのメソッドを呼び出すループです。簡易版は、次のようになります。

public DataTable MyMethod() 
{ 
    DataTable MyDataTable = new DataTable(); 
    <add columns to the data table> 

    for (int counter = 1; counter <= MaxCounter; counter++) 
    { 
     <<generate some values>> 

     ComputeOutputsByRecipe(id, ref MyDataTable); 
    } 

    return MyDataTable; 
} 

private void ComputeOutputsByRecipe(int RecipeID, ref DataTable Results) 
{ 
    switch (RecipeID) 
    { 
     case 1: 
      ProcessRecipe_1(ref Results); 
      break; 

     case 2: 
      <repeat for supported recipe IDs> 
    } 
} 

private void ProcessRecipe_1(ref DataTable Results) 
{ 
    <do some processing> 

    DataRow dr = Results.NewRow(); 
    <populate the new data row> 
    Results.Rows.Add(dr); 
} 

だから、私は何を探していると、複数のプロセッサ上で実行されている複数のスレッドを活用するために「Paralel.For」と「について」を置き換えるです。しかし、ループの各反復は参照パラメータに書き込むので、スレッドの安全性が懸念されます。今...データがこのデータテーブルに書き込まれる順序は重要ではありません。そして、私はループが完了するまでデータテーブルから読みません。だから私はこれが問題だとは思わない。しかし、Add()はインスタンスメソッドなので、何が起こるか心配です。

私の例のforループがParalel.For()に置き換えられ、ループが終了するまでデータテーブルから読み込まない場合、このようなデータテーブルに行を追加するのは安全ですか?完了しましたか?

+0

私はリソース集中型のビットがあなたの 'ProcessRecipe_1'メソッドだと思いますか? 'Parallel.For()'を利用して、各ループのメインスレッドでデリゲートを呼び出して、テーブルに行を実際に追加することができます。 –

+0

'ref'を使って' DataTable'を渡す理由はないことに注意してください。あなたはその変数だけを変更せず、その値だけを変更します。 – Servy

答えて

3

いいえ、安全ではありません。 DataTableは、複数の同時スレッドから変更されるようには設計されていません。

正常に動作するように、アクセスを同期させる必要があります。

+0

'Add()'の権利を実行する前にデータテーブルをロックする必要がありますか? – DeadZone

+0

@DeadZoneあなたはそれへの*すべてのアクセスを同期する方法でしょう。 – Servy

関連する問題