xpo-403900-best-practices-how-to-resolve-cannot-modify-dictionary-because-thread-safe-data-layer-uses-it.md
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.
XPDictionary before you initialize ThreadSafeDataLayer.ThreadSafeDataLayer at startup.
Dictionary cannot be modified while it's being used by the ThreadSafeDataLayer. ClassInfo modified or created: 'DxSample.Module.BusinessObjects.Contact'
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);
Public Shared ReadOnly Property DataStore() As IDataStore
Get
Return fDataStore
End Get
End Property
' In the application entry point
Private connectionString As String = "my connection string"
connectionString = XpoDefault.GetConnectionPoolString(connectionString)
fDataStore = XpoDefault.GetConnectionProvider(connectionString, AutoCreateOption.None)
XpoDefault.DataLayer = New SimpleDataLayer(DataStore)
' In a background thread
Dim dictionary As XPDictionary = New ReflectionDictionary()
Dim dataLayer As IDataLayer = New SimpleDataLayer(dictionary, Program.DataStore)
Dim session As New Session(dataLayer)
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.
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