2010-12-07 5 views
4

私は以下のコードフラグメントを別のスレッドからアクセスしています。異なるスレッドはオブジェクトを共有します

  try 
     {    
      this.RefreshSettings(); 
      DateTime lastChecked = DateTime.Now.AddMilliseconds(-1 * m_Settings.Interval); 

      while (Run) 
      { 
       if ((DateTime.Now - lastChecked).TotalMilliseconds >= this.m_Settings.Interval) 
       { 
        lastChecked = DateTime.Now; 

        if (this.ShouldNotify()) 
        { 
         object LockObj = new object(); 

         lock (LockObj) 
         { 
          this.Notify(); 
         } 
        } 
       } 
       //Thread.Sleep(this.m_Settings.Interval); 
      } 
     } 

あなたが見ることができるように、私だけの時間ごとに一定間隔(m_settings.Interval)の後に呼び出されるShouldNotify()メソッドをしたいです。しかし、私の問題は、2つ以上のスレッドがNotifyIfNecesarry関数を呼び出した場合、lastChecked変数を共有していることです。したがって、あるスレッドがその値をdateTime.Nowにリセットすると、他のスレッドもその値をリセットします。

どのように各スレッドが独自のlastCheckedを保持するようにそのメソッドを記述できますか? Thread.Sleepの使用はオプションではありません。なぜなら、bool Runの値をfalseに変更すると、ループを即座に終了する必要があるからです。私がthread.Sleepを持っていて、スレッドがスリープしている場合、プログラムはwhile条件をチェックするまで終了しないので、m_settings.Intervalのmak遅延が起こる可能性があります。

+2

間 を共有していないですこのメソッドの他のインスタンスローカル変数はスレッド間で共有されないので、何かが欠けているのですか? – CodingGorilla

+0

このコードはどこですか?スレッドの実行中か、別のクラスにありますか? – Aliostad

+0

@コーディングゴリラ:lastCheckedはローカルです。私はローカル変数がスレッドによって共有されていないことに気づいていませんでした。私は他の何かが問題を引き起こしているに違いないと思う。 – xbonez

答えて

1

あなたのループをスキップして、たとえばSystem.Timers.Timerのために使用する必要があります。そして、あなたのロックも外れています。インスタンス外ではなくループ外で作成する必要があります。ロックを使用する場合、すべてのスレッドは同じオブジェクトにロックする必要があります。各スレッドは、独自の を維持 ように、私は、そのメソッドを書くことができますどのように

+1

@Mickael私はあなたが「あなたのループをスキップする」という意味ではないと思う。このフレーズはhttp:// enのために笑顔になるかもしれませんが。wikipedia.org/wiki/Skip_to_My_Lou –

+0

私はそれに気づき、答えを編集しました:)私にも笑顔を与えました。 –

1

ローカルで作成されたオブジェクトではlockには意味がありません。すべてのスレッドは同じインスタンス上にlockでなければなりません。そうでなければ同期はありません。

このコードを実行するすべてのスレッドは、新しく作成されたインスタンスobjectへのローカル参照を持つため、以下のコードは意図した通りに動作しません。

また
object LockObj = new object(); 

lock (LockObj) 
{ 
    this.Notify(); 
} 

、​​はローカル値型であることから、各スレッド独自のコピーを持っています。

0

あなたはすでにこれをやった

をlastChecked。

コーディングゴリラは正しいです。

lastChecked変数が ローカル...ローカル変数は、私は何かが欠けていない限り、 `lastChecked`変数はローカルですが、あなたはそれはと共有されていますと言うスレッド

関連する問題