3

.NET 2.0 を実行している Web サイトがあり、ASP.Net HttpRuntime.Cache の使用を開始して、頻繁なデータ ルックアップの結果を保存し、データベース アクセスを削減しました。

スニペット:

 
lock (locker)
{
    if (HttpRuntime.Cache[cacheKey] == null)
    {
        HttpRuntime.Cache.Insert(cacheKey, GetSomeDataToCache(), null, DateTime.Today.AddDays(1), Cache.NoSlidingExpiration);       
    }
    return ((SomeData)HttpRuntime.Cache[cacheKey]).Copy();
}

キャッシュを見たいときはいつでも悲観的にロックしています。ただし、ロックのオーバーヘッドが発生しないように、代わりにキャッシュ値を確認した後にロックすることを提案するさまざまなブログが Web に投稿されているのを見てきました。チェック後に別のスレッドがキャッシュに書き込んだ可能性があるため、これは正しくないようです。

最後に私の質問は、これを行う「正しい」方法は何ですか? 正しいスレッド同期オブジェクトを使用していますか? ReaderWriterLockSlim() は認識していますが、.NET 2.0 を実行しています。

4

4 に答える 4

10

私の知る限り、Cache オブジェクトはスレッド セーフであるため、ロックは必要ありません。

于 2009-01-15T17:40:33.063 に答える
5

.NET の Cache オブジェクトはスレッド セーフであるため、ロックは必要ありません。参照: http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx

于 2009-01-15T17:45:59.107 に答える
1

あなたのコードはおそらく、そのアイテムが 1 日間キャッシュされ、最後の行で常にそのデータが提供されると思わせるかもしれませんが、そうではありません。他の人が言ったように、キャッシュ操作は同期されているため、その時点でロックしないでください。

正しい方法については、こちらをご覧ください。

于 2009-07-11T17:25:20.937 に答える
0

スレッドセーフ。コードが完了するまで、他のすべてのプロセスが待機していることを意味しますか?

スレッド セーフとは、取得したアイテムが「半分にカット」されたり、アイテムの読み取りと同時にキャッシュが更新されて部分的に破棄されたりしないことを確認できることです。

item = cache.Get(key);

しかし、その後何をするにしても、別のスレッドがキャッシュ (または他の共有リソース) で操作できます。フェッチされたアイテムがnullであるかどうかに基づいてキャッシュに何かをしたい場合、別のリーダーにサービスを提供する数CPU命令の先にある独自のコードの他のインスタンスによって、それがまだ修正されていないことを100%確信することはできません。あなたのオンライン モーター マガジンの同じページ。

あなたはいくつかの不運が必要です。数行のコード appart で、他のプロセスがアトミックではない同じキャッシュ オブジェクトに干渉するリスクは、ランダムに小さくなります。しかし、そうなった場合、なぜシボレーのイメージが 2 ページの小さなスーツケースになるのかを理解するのに苦労するでしょう。

于 2015-05-23T08:59:34.780 に答える