PersistentDictionary unusable in web apps and unit tests?

Jun 23, 2010 at 11:12 PM
In my web application and unit tests, I keep getting TempPathInUse exceptions when I instantiate a new PersistentDictionary with a directory already used. It seems like I can only have one instance per directory active at a given time, and the only way I could make it work, is to use only local variables and wrap them in using statements. That doesn't look very multi-threaded to me. This thing will blow up under load as more users will try to instantiate dictionaries for the same folder before the existing instances are disposed.
Jun 24, 2010 at 5:40 PM

You cannot create multiple PersistentDictionaries with the same path, but a PersistentDictionary can be used by multiple threads. In your case you can make the PersistentDictionary a global variable and let all the users access it. If you want to perform compound operations (e.g. Get a value, do a calculation and then set the value) you will need to synchronize that yourself.

Jun 24, 2010 at 7:51 PM
Edited Jun 24, 2010 at 7:54 PM
Yes, I finally discovered that. But it would be nice if the documentation and all code samples made an effort to explain this. One can always argue that if I had used the regular Dictionary, I would have to make it static in order to keep the values over a meaningful period. Hence the PersistantDictionary should be used the same way. But that is not obvious: * The PersistantDictionary saves data to disk, so the data is never lost. If I can create one instance and dispose it, then create another instance and observe the data is already in there, then it's not obvious why I can't create multiple instances at once. * At least one example assigns the PersistentDictionary to a local variable, hinting this is proper usage. * Database frameworks like NHibernate and Linq To Sql can create multiple objects and query the database with all of them. * The API doesn't hint the PersistentDictionary must be a singelton. I think the PersistentDictionary should handle the singelton on the inside, using the Monostate Pattern, and also do the proper multithread locking / synchronisation on all write operations. Now that I have offered my critique, it's only fair to also offer some of my time to help you change the code, if you should happen to agree with me. I am not experienced with multithread programming, so I will need help to set up the proper unit tests.
Jun 25, 2010 at 4:12 PM

For the .NET class I want to match the semantics of dictionaries (which have to be singletons) and files (opening the same file twice isn't advisable). Internally the PersistentDictionary does do the proper locking on multithreaded operations.

The easiest way to create the behaviour your want is to have a factory method that creates the dictionaries. It can keep a Dictionary<string, WeakReference>, which tracks the open dictionaries and will return a reference to an already opened dictionary if the same dictionary is opened twice.

As you had this problem the documentation is clearly lacking -- I will try to provide a better explanation and example.