Application
は古いASPテクノロジから残りのデータストアです。これにはグローバルロックが1つあります。 Application.Lock()
に電話すると、すべてのスレッドのApplicationオブジェクトへのすべてのアクセスがブロックされます。
一方ASP.NETで導入された新しいCache
オブジェクトは、あなた自身のロックのセマンティクスを使用することができます。 .NETのlock
ステートメントを使用すると、Webアプリケーションを可能な限り並列に保ちながら、Cacheオブジェクトへのスレッドセーフなアクセスを確保できます。 lock
ブロックを終了するとロックが解除されることが保証されているため、lock
ステートメントはより安全です。アプリケーションオブジェクトはそれを保証しません。キャッシュはまた、キャッシュのためにはるかに適した自動期限切れメカニズムを提供します。また、依存関係やオプションの優先順位に基づいてキーを期限切れにすることもできますが、もちろんアプリケーションオブジェクトには欠けています。
私はApplication
Cache
以上のオブジェクトを使用する理由を見ません。
例:あなたは、キャッシュ内の百個のアイテムを持っていて、それが既に存在しない場合は、キャッシュに格納する単一の項目があるとしましょう。すべてのは、彼らが完全に無関係であってもブロックされているApplicationオブジェクトへのアクセスこのシナリオでは
if(Application["someData"] == null)
{
Application.Lock();
if(Application["someData"] == null)
{
Application["someData"] = getValue(); //a very long time consuming function
}
Application.Unlock();
}
:あなたはApplication
を使用するときは、これを行います。 getValue()
が例外を発生させた場合、ロックが解除されないため、アプリケーションがハングします。 try
.. finally
をラップして、安全であることを確認する必要があります。 myLockObject
へのアクセスを必要とするだけのコードブロックが待機していることになる。この場合、
if(Cache["someData"] == null)
{
lock(myLockObject) // or other shared lock for that single value
{
if(Cache["someData"] == null)
{
Cache["someData"] = getValue();
}
}
}
:一方
Cache
オブジェクトを使用して、あなたがこれを行います。 Cache
にアクセスする他のユーザーは、並行して動作します。 getValue()
が例外をスローする場合は、ロックを解除しても問題は発生せず、ほかのスレッドは実行を継続できます。
キャッシュコレクションは、Microsoftによってスレッドセーフになっています。外部ロックは必要ありません。 –
キャッシュ自体はスレッドセーフであるため、アトミック性は一貫性ではありません。上のサンプルコードを見てください。 'lock'文がなければ、スレッドセーフであるかどうかにかかわらず、複数のスレッドが同時に' getValue() 'を呼び出すことになります。 –
そして、私はこのダウンボートの背後にある理由を「この答えは役に立たない」と言います。本当に? –