Does my IBackingStore need to be thread safe ?

Topics: Caching Application Block
Jun 28, 2009 at 2:08 PM
Edited Jun 28, 2009 at 2:12 PM

Hi,

The documentation of the enterprise library says :

Because of the way the Cache object operates, you are guaranteed that any backing store will be called in a single-threaded manner. This means you do not have to make your implementation thread safe.

And concerning the CacheManager :

Every method call made through the CacheManager object is thread safe.

But a simple test proves the contrary :

Here is my custom backing store (only the Add method is relevant)

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
}

And here is a test wich access to the same CacheManager through two differents threads :

 

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");

 

The Add method is executed two times in two differents thread (because it throws the "NotImplementedException" of the Add method).

Is something wrong with my code or the documentation of the enterprise library is wrong ?

 

 

Jun 29, 2009 at 7:02 AM
Edited Jun 29, 2009 at 7:19 AM

The locking done by the Cache object is on the per key (of the cache item) level.  You can test this by changing item2 to item1.  The assumption I think is that adding items of different keys shouldn't matter, it is only concerned if concurrent call to the Add method uses the same key.

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com