2009-03-13 17 views
1

私は適切に理解できないコードが少しあります。私が持っている問題は、いくつかの時点で時間内のすべてのスレッドがあるように見えるということですC#モニタクラスのマルチスレッドの問題 - 生存可能ですか?

lock (lockObject) 
{ 
    if (!Monitor.TryEnter(lockObject)) 
    Monitor.Wait(lockObject); 

    //do stuff... 
    Monitor.PulseAll(lockObject); 
} 
Monitor.Exit(lockObject); 

:問題は、プログラムがマルチスレッドので、私はこれを書いて同期させる必要があるコードのビットがある範囲内にあるということです眠っている - 誰かが理由を伝えることができる?プログラムはほとんど無駄にCPUを消費し続けますが、作業は行われません。プログラムをトレースすると、ある時点ではスレッドはアクティブになっていませんが、多くのスレッドがスリープ状態にあることがわかりました。ほとんどの場合(開発者の場合は - 常に)モニターの前に0.5mが置かれていますが、自分では理解できません... ...

私 - 事前に感謝します。

+0

LockObjectは、あなたがMonitor.TryEnterをオンにしているのと同じものをロックしていますか、またはLockObject型をロックしていますか? –

+0

はい - これは古典的なタイプミスです – Gambrinus

答えて

1

LockObjectlockObjectの間に違いはありますか?それは明らかではありません...

しかし!それらが異なるオブジェクトである場合は、まず、Waitにはロックがありません...そしてTryEnterはタイムアウトを指定した場合にのみfalseを返します。そのコードは正確に何をしようとしていますか?

文脈がなければ、PulseAllおよびWaitが何をするように設計されているかは完全にはっきりしていません。 here空き領域が満杯(Wait)したときにキューをブロックしたり、空き領域(PulseAll)などがあるときにキューを解放するために使用されます。スレッド間の完全なやり取りなしにスレッドコードをデバッグすることは困難です。

それはあなただけが必要な場合がありますように聞こえる:

lock (lockObject) 
{ 
    // do stuff 
} 

私が見ることができる2つの当面の問題があります。最初に、あなたが取るロック(つまり例外)を常に解放することは明らかではありません。 Enter/Exitにはlockを使用してみてください。正しいと思われます。

第2;すべてのスレッドがWaitに電話をかけると...誰が目を覚ますでしょうか?彼らは何を待っていますのために?提示されたとおり:はい、彼らはすべて無期限に眠ります。

3

私は最初のロックステートメントを打ち明けていますが、あなたはロック(lockObject)(小文字)を意味しています。

私はあなたがここで少しロックを誤解していると思います。あなたのコードのifブロックは真実ではありません。そのロック(lockObject)がある理由は、実際にあなたがあなたが既にロックを所有している場合はブロックをヒットし、TryEnterは必ず成功するはずの時間で、次の

Monitor.Enter(lockObject); 
try { 
... 
} finally{ 
Monitor.Exit(lockObject); 

にexapands。

+0

変数を指定または取得します;-p情報の場合、このパターンはC#4.0で変更されているようです:http://blogs.msdn.com/ericlippert/archive/2009/03/06 /locks-and-exceptions-do-not-mix.aspx –

+0

@Marc、はい、この変更を見るのは非常にエキサイティングです。 – JaredPar

+0

@Marc、面白いリンク - ありがとう – Gambrinus

1

これは奇妙な設定です。 'LockObject'は 'lockObject'と同じですか?それとも、それはタイプミスですか?それらが同じ場合は、すでにロックしているものでMonitor.TryEnterを呼び出す必要がないため、設定が冗長です。 'LockObject'が別のオブジェクトである場合、なぜMonitor.Exitをlockステートメント内に移動しないのですか?

関連する問題