2012-04-22 16 views
6

Applicationクラスは、スレッドの安全性をサポートするためのLock機構を有しています。アプリケーション:asp.netでのロック機構

私たちが知っているように - Applicationがグローバルにアクセスすることができます。

サンプル:

Application.Lock(); 
Application["MyCode"] = 21; 
Application.UnLock(); 

OK。

しかし

またCacheはグローバルにアクセス可能である(とdoesntのロックメカニズムを持っているし、アイテムを追加/削除するためにも使用)

なぜApplicationは、ロック機構を持っており、Cacheはしないのですか?

答えて

6

Applicationは古いASPテクノロジから残りのデータストアです。これにはグローバルロックが1つあります。 Application.Lock()に電話すると、すべてのスレッドのApplicationオブジェクトへのすべてのアクセスがブロックされます。

一方ASP.NETで導入された新しいCacheオブジェクトは、あなた自身のロックのセマンティクスを使用することができます。 .NETのlockステートメントを使用すると、Webアプリケーションを可能な限り並列に保ちながら、Cacheオブジェクトへのスレッドセーフなアクセスを確保できます。 lockブロックを終了するとロックが解除されることが保証されているため、lockステートメントはより安全です。アプリケーションオブジェクトはそれを保証しません。キャッシュはまた、キャッシュのためにはるかに適した自動期限切れメカニズムを提供します。また、依存関係やオプションの優先順位に基づいてキーを期限切れにすることもできますが、もちろんアプリケーションオブジェクトには欠けています。

私はApplicationCache以上のオブジェクトを使用する理由を見ません。

例:あなたは、キャッシュ内の百個のアイテムを持っていて、それが既に存在しない場合は、キャッシュに格納する単一の項目があるとしましょう。すべてのは、彼らが完全に無関係であってもブロックされている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()が例外をスローする場合は、ロックを解除しても問題は発生せず、ほかのスレッドは実行を継続できます。

+1

キャッシュコレクションは、Microsoftによってスレッドセーフになっています。外部ロックは必要ありません。 –

+3

キャッシュ自体はスレッドセーフであるため、アトミック性は一貫性ではありません。上のサンプルコードを見てください。 'lock'文がなければ、スレッドセーフであるかどうかにかかわらず、複数のスレッドが同時に' getValue() 'を呼び出すことになります。 –

+0

そして、私はこのダウンボートの背後にある理由を「この答えは役に立たない」と言います。本当に? –

関連する問題