2009-06-28 34 views
0

企業ライブラリのドキュメントは言う:私のIBackingStoreはスレッドセーフである必要がありますか?

ため、キャッシュオブジェクトの動作方法を、あなたはシングルスレッドな方法で任意のバッキングストアが と呼ばれること を保証されています。この は、 の実装スレッドを安全にする必要はありません。

とのCacheManagerに関する:

のCacheManagerオブジェクトを介して行われたすべてのメソッド呼び出しは、スレッドセーフです。

しかし、簡単なテスト反対を証明する:

ここにここに私のカスタムバッキングストア(のみAddメソッドが関連している)

public class MyStore : IBackingStore 
{ 
    volatile bool isEntered = false; 
    #region IBackingStore Members 

    public void Add(CacheItem newCacheItem) 
    { 
     if(isEntered) 
      throw new NotImplementedException(); 
     isEntered = true; 

     Thread.Sleep(1000); 

     isEntered = false; 

    } 

    public int Count 
    { 
     get 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public void Flush() 
    { 
     throw new NotImplementedException(); 
    } 

    public System.Collections.Hashtable Load() 
    { 
     return new System.Collections.Hashtable(); 
    } 

    public void Remove(string key) 
    { 
     throw new NotImplementedException(); 
    } 

    public void UpdateLastAccessedTime(string key, DateTime timestamp) 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 

    #region IDisposable Members 

    public void Dispose() 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

とが同じのCacheManagerへのテストウィッヒアクセスです

DictionaryConfigurationSource configSource = new DictionaryConfigurationSource(); 
CacheManagerSettings cacheSettings = new CacheManagerSettings(); 
configSource.Add(CacheManagerSettings.SectionName, cacheSettings); 
CacheStorageData storageConfig = new CacheStorageData("MyStorage", typeof(MyStore)); 
cacheSettings.BackingStores.Add(storageConfig); 
CacheManagerData cacheManagerData = new CacheManagerData("CustomCache", 120, 100, 5, storageConfig.Name); 
cacheSettings.CacheManagers.Add(cacheManagerData); 
cacheSettings.DefaultCacheManager = cacheManagerData.Name; 


CacheManagerFactory cacheFactory = new CacheManagerFactory(configSource); 
ICacheManager cacheManager = cacheFactory.CreateDefault(); 
Thread thread = new Thread(() => 
{ 
    cacheManager.Add("item1", "odaiu"); 
}); 
thread.Start(); 
cacheManager.Add("item2", "dzaoiudoiza"); 

Addメソッドは2つの異なるスレッドで2回実行されますそれはAddメソッドの "NotImplementedException"をスローします)。

私のコードに問題がありますか、エンタープライズライブラリのドキュメントが間違っていますか?

答えて

0

ドキュメントはこれについて明示的なので、私はドキュメントを信頼します。

あなたの証拠には、クラスの明示的なマルチスレッド・ユースケースが作成されているという点で欠陥があります。特定のインターフェイスには、スレッドセーフなものは何もありません。だからこれは確かに失敗するでしょう。

エンタープライズライブラリは、スレッドセーフな方法でインターフェイスを管理することを保証しています。内部的には、クラスのスレッドの安全性を管理するために注意します。

注:このライブラリに関する具体的な知識はありませんが、明示的に書かれているドキュメントは信頼できます。

0

私はJaredParに同意します。これは、ドキュメントにアクセスが同期されているため、トレッドセーフであると述べています。しかし、提供されたバッキングストアの実装のソースコードを見ると、マルチスレッド環境で実行されることを期待してコーディングされていることがわかります。だからおそらくこれは古くなった文書のケースです。

次の抜粋は、EntLib 5.0のIsolatedStorageBackingStoreからのもので、4.1の実装は同じだと考えています。抜粋は分かりやすくするための1つの方法に過ぎませんが、基本となるIsolatedStorageFileへのすべてのアクセスはロックされています。

/// <summary> 
/// Adds new item to persistence store 
/// </summary> 
/// <param name="storageKey">Unique key for storage item</param> 
/// <param name="newItem">Item to be added to cache. May not be null.</param> 
protected override void AddNewItem(int storageKey, CacheItem newItem) 
{ 
    lock (store) 
    { 
     string storageLocation = GenerateItemLocation(storageKey); 
     IsolatedStorageCacheItem cacheItem = 
      new IsolatedStorageCacheItem(store, storageLocation, this.encryptionProvider); 
     cacheItem.Store(newItem); 
    } 
} 
関連する問題