Add locks for the dictionary.

This commit is contained in:
Nikolaj
2021-08-24 10:38:38 +02:00
parent c690d5f3ba
commit 6c21cb30d3

View File

@@ -11,30 +11,40 @@ namespace Umbraco.Cms.Core.Cache
INotificationHandler<DataTypeSavedNotification>,
INotificationHandler<DataTypeDeletedNotification>
{
private readonly Dictionary<string, Dictionary<int, IDataValueEditor>> _valueEditorCache = new();
private readonly Dictionary<string, Dictionary<int, IDataValueEditor>> _valueEditorCache;
private readonly object _dictionaryLocker;
public ValueEditorCache()
{
_valueEditorCache = new Dictionary<string, Dictionary<int, IDataValueEditor>>();
_dictionaryLocker = new object();
}
public IDataValueEditor GetValueEditor(IDataEditor editor, IDataType dataType)
{
// We try and get the dictionary based on the IDataEditor alias,
// this is here just in case a data type can have more than one value data editor.
// If this is not the case this could be simplified quite a bit, by just using the inner dictionary only.
IDataValueEditor valueEditor;
if (_valueEditorCache.TryGetValue(editor.Alias, out Dictionary<int, IDataValueEditor> dataEditorCache))
// Lock just in case multiple threads uses the cache at the same time.
lock (_dictionaryLocker)
{
if (dataEditorCache.TryGetValue(dataType.Id, out valueEditor))
// We try and get the dictionary based on the IDataEditor alias,
// this is here just in case a data type can have more than one value data editor.
// If this is not the case this could be simplified quite a bit, by just using the inner dictionary only.
IDataValueEditor valueEditor;
if (_valueEditorCache.TryGetValue(editor.Alias, out Dictionary<int, IDataValueEditor> dataEditorCache))
{
if (dataEditorCache.TryGetValue(dataType.Id, out valueEditor))
{
return valueEditor;
}
valueEditor = editor.GetValueEditor(dataType.Configuration);
dataEditorCache[dataType.Id] = valueEditor;
return valueEditor;
}
valueEditor = editor.GetValueEditor(dataType.Configuration);
dataEditorCache[dataType.Id] = valueEditor;
_valueEditorCache[editor.Alias] = new Dictionary<int, IDataValueEditor> { [dataType.Id] = valueEditor };
return valueEditor;
}
valueEditor = editor.GetValueEditor(dataType.Configuration);
_valueEditorCache[editor.Alias] = new Dictionary<int, IDataValueEditor> { [dataType.Id] = valueEditor };
return valueEditor;
}
public void Handle(DataTypeSavedNotification notification) =>
@@ -45,13 +55,16 @@ namespace Umbraco.Cms.Core.Cache
private void ClearCache(IEnumerable<int> dataTypeIds)
{
// If a datatype is saved or deleted we have to clear any value editors based on their ID from the cache,
// since it could mean that their configuration has changed.
foreach (var id in dataTypeIds)
lock (_dictionaryLocker)
{
foreach (Dictionary<int, IDataValueEditor> editors in _valueEditorCache.Values)
// If a datatype is saved or deleted we have to clear any value editors based on their ID from the cache,
// since it could mean that their configuration has changed.
foreach (var id in dataTypeIds)
{
editors.Remove(id);
foreach (Dictionary<int, IDataValueEditor> editors in _valueEditorCache.Values)
{
editors.Remove(id);
}
}
}
}