6

Applicationasp.netのクラスには、Lockスレッド セーフをサポートするメカニズムがあります。

ご存じのとおり、Applicationグローバルにアクセスできます。

サンプル :

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

わかった。

しかし

また、Cacheグローバルにアクセス可能です(ロック機構がなく、アイテムの削除/追加にも使用されます)

では、なぜApplicationロック機構があり、そうでCacheないのですか?

4

1 に答える 1

6

Application古い ASP テクノロジから残っているデータストアです。単一のグローバル ロックがあります。Application.Lock()すべてのスレッドで Application オブジェクトへのすべてのアクセスを呼び出すと、ブロックされます。

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

オブジェクトを使用Applicationする理由はありません。Cache

例: キャッシュに 100 個のアイテムがあり、まだそこにない場合にキャッシュに保存したいアイテムが 1 つあるとします。を使用するときは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

一方、Cacheオブジェクトを使用する場合は、次のようにします。

if(Cache["someData"] == null)
{
    lock(myLockObject)  // or other shared lock for that single value
    {
        if(Cache["someData"] == null)
        {
            Cache["someData"] = getValue();
        }
    }
}

この場合、アクセスが必要なコード ブロックのみmyLockObjectが待機します。にアクセスする他のものCacheは、問題なく並行して実行されます。また、例外がスローされた場合getValue()、ロックは問題なく解放され、他のスレッドが実行を継続できます。

于 2012-04-22T14:59:14.683 に答える