Skip to main content
All docs
V24.1

How to Resolve 'Cannot Modify Dictionary Because ThreadSafeDataLayer Uses It'

  • 3 minutes to read

#What Does the Error Message Mean?

The ThreadSafeDataLayer class represents a data access layer for multi-threaded applications. This class ensures immutability of XPDictionary and XPO metadata. You should initialize XPDictionary before you create ThreadSafeDataLayer.

Important

You shouldn’t create new classes/properties or add attributes after you instantiate a ThreadSafeDataLayer object. Otherwise, the ‘Cannot Modify Dictionary because ThreadSafeDataLayer Uses It’ error occurs.

ThreadSafeDataLayer uses the Fail Fast technique to avoid synchronization issues. When you add a new class to XPDictionary or modify XPO metadata at runtime, ThreadSafeDataLayer immediately throws an exception.

#How to Fix the Error?

  • Ensure that you add all persistent classes to XPDictionary before you initialize ThreadSafeDataLayer.
  • Ensure that you initialize ThreadSafeDataLayer at startup.
  • Check the class name in the error message. Add this class to XPDictionary at startup.

Dictionary cannot be modified while it's being used by the ThreadSafeDataLayer. ClassInfo modified or created: 'DxSample.Module.BusinessObjects.Contact'

#Review Code that Modifies XPO Metadata

  • Turn off the Just My Code option in Visual Studio.
  • Review the call stack. Open the Call Stack window and check the output for a non-DevExpress method.
  • Go to the method definition (if found) and see if it contains XPDictionary.AddClassInfo, XPDictionary.CreateClass, XPClassInfo.CreateMember, or other method calls. These methods can modify XPDictinary. You need to create XPO metadata before you initialize ThreadSafeDataLayer or you can choose not to use ThreadSafeDataLayer (see an example below).

The following example demonstrates how to use a connection pool and SimpleDataLayer to work with XPO objects in a background thread.

public static IDataStore DataStore {
    get { return fDataStore; }
}

// In the application entry point
string connectionString = "my connection string";
connectionString = XpoDefault.GetConnectionPoolString(connectionString);
fDataStore = XpoDefault.GetConnectionProvider(connectionString, AutoCreateOption.None);
XpoDefault.DataLayer = new SimpleDataLayer(DataStore);

// In a background thread
XPDictionary dictionary = new ReflectionDictionary();
IDataLayer dataLayer = new SimpleDataLayer(dictionary, Program.DataStore);
Session session = new Session(dataLayer);

#Generic Persistent Classes Don’t Map to Specific Tables

When you use a generic type with a specific argument, XPO creates new persistent metadata. Do not create metadata dynamically. Decorate generic classes with the NonPersistentAttribute attribute, declare non-generic descendants, and map them to tables.

#‘Cannot modify Dictionary because ThreadSafeDataLayer uses it’ in XAF

In XAF applications, this error occurs when new records are added to the XPObjectType table after the data access layer has been initialized. Use the DBUpdater tool to update your database and fill the XPObjectType table in advance.

See Also