2012-04-18 17 views
1

私の生徒の一人がマルチスレッドを説明する例を作成するように求められました。私はこの擬似的な例を考え出しました。この擬似例はスレッドを生成し、ループしている間にランダムな回数とスリープを行います。私は各スレッドを識別するためにGuidを使用するDictionaryを介してこれらのスレッドを追跡しています。MultiThreadingの例 - 私は辞書をロックする必要があります

ディクショナリは、これらのスレッドを監視し、おそらくそれらを「強制終了」するために使用されるページで使用できます。

これは合理的に見えるん:

ここ
public class LongProcess 
    { 
     public static Dictionary<Guid, LongProcess> Monitor = new Dictionary<Guid, LongProcess>(); 

     public Guid Id { get; set; } 

     public int Iterations { get; set; }//number of loops 

     public int SleepFactor { get; set; }//rest period while looping 

     public int CompletedIterations { get; set; }//number of completed loops 


     void Process() 
     { 
      for(var i = 0 ; i < Iterations; i++) 
      { 
       Thread.Sleep(1000*SleepFactor); 
       SleepFactor = new Random(DateTime.Now.Millisecond).Next(1, 5); 
       this.CompletedIterations++; 
      } 
     } 

     public void Start() 
     { 
      Monitor.Add(Id, this); 
      var thread = new Thread(new ThreadStart(Process)); 
      thread.Start(); 
     } 
    } 

は、このクラスが使用される方法です:

var id = Guid.NewGuid(); 
    var rnd = new Random(DateTime.Now.Millisecond); 
    var process = new LongProcess 
         { 
          Iterations = rnd.Next(5, 20), 
          SleepFactor = rnd.Next(1, 5), 
          Id = id 
         }; 
    process.Start(); 

任意のアイデアをいただければ幸いです。

+0

スレッド内で 'Dictionary 'にアクセスしていないので、2番目のコードブロックがマルチスレッドで実行されている場合を除き、アクセスをロックする心配はありません。 –

+0

私が得られる答えは、開発者の個人的な好みにあまりにも多すぎると思います。あなたのプログラムが動作していて、コードの特定の部分を改善したいのであれば、その部分をハイライトして一般的な質問をしてください。 – Churk

+0

@Churk - この質問には何も間違いありません。個人的な好みの問題。 –

答えて

4

process.Startへのすべての呼び出しが同じスレッドで発生する限り、LongProcessクラス内で開始されるバックグラウンドスレッドではアクセスされないため、辞書をロックする必要はありません。つまり、クラスLongProcessはスレッドセーフではありませんが、現在のコードでは問題ありません。
安全のために、ロックを回避するには、.NET4の新しいConcurrentDictionary<TKey, TValue>を使用することができます。あなたは辞書をロックする必要があります

+0

Daniel、ありがとう。だから私が自分の辞書をつかんでLongProcessにアクセスしてステータスを調べると、別のスレッドによって更新されたLongProcessについて心配する必要がありますか? –

+0

@ek_ny:これは本当にどこで起こるかによって異なります。一度に1つのプロセスだけが辞書にアクセスする場合は、心配する必要はありません。ただし、新しいLongProcessを開始できるボタンが付いた小さなWebサイトがある場合は、複数のユーザーが同時にそのボタンをクリックできるため、辞書をロックするか、コンカレント辞書を使用する必要があります。 –

+0

MVCアプリケーションのコントローラのアクションメソッドについてはどうですか?公共化するJsonResultステータス() は{返す 新しい化するJsonResult {データ= LongProcess.Monitor.Values、 JsonRequestBehavior = JsonRequestBehavior.AllowGet }。 } –

0

は、それが複数のスレッドによってアクセスされるか、

+0

3.5の検索が容易なバージョン – asawyer

+0

-1:正しくありません。彼のコードでは、辞書は複数のスレッドによってアクセスされていません。 –

2

他の人が周りにロックについて答えてきた設計により、スレッドセーフであるSystem.Collections.Concurrent.ConcurrentDictionaryを使用することができています辞書と私は彼らに同意するだろう。

私が変更することの1つは、プロパティの設定者です。それらは現在公開されています。つまり、スレッドが繰り返し実行されている間に基礎となる値を変更でき、偉大なAPI設計ではありません。

クラスにコンストラクタを追加して、必要なパラメータを取得し、セッターをプライベートにすることで、間違ってクラスの値を変更して奇妙な結果につなげることはありません。

関連する問題