2009-06-28 48 views
0

企业库的文件说:我的IBackingStore需要线程安全吗?

因为Cache对象进行操作,保证您 任何后备存储将被称为在单线程方式 的方式。这 意味着你不必让你的 实现线程安全。

以及有关的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方法在两个不同的线程中执行两次(因为它会抛出Add方法的“NotImplementedException”)。

我的代码或企业库的文档有问题吗?

回答

0

由于文档对此非常明确,所以我会相信文档。

您的证明存在缺陷,因为您正在为该类创建一个明确的多线程用例。对于使线程安全的特定接口没有任何固有的东西。所以这肯定会失败。

企业库正在保证他们将以线程安全的方式管理接口。他们在内部会小心地管理班级的线程安全。

注意:我对这个库没有任何具体的知识,但是对于明确的文档,我会信任它。

0

我同意JaredPar的说明文档状态访问是同步的,因此踩踏。但是,如果您查看实现已交付后备存储的源代码,您将看到它的编码期望在多线程环境中运行。所以也许这是一个陈旧的文档的情况。

以下摘录来自EntLib 5.0中的IsolatedStorageBackingStore,认为4.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); 
    } 
}