diff --git a/src/Umbraco.Core/IDisposeOnRequestEnd.cs b/src/Umbraco.Core/IDisposeOnRequestEnd.cs
new file mode 100644
index 0000000000..cf1ec3a177
--- /dev/null
+++ b/src/Umbraco.Core/IDisposeOnRequestEnd.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Umbraco.Core
+{
+ ///
+ /// Any class implementing this interface that is added to the httpcontext.items keys or values will be disposed of at the end of the request.
+ ///
+ public interface IDisposeOnRequestEnd : IDisposable
+ {
+ }
+}
diff --git a/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs b/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs
index a97f1fe976..7cc130600b 100644
--- a/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs
+++ b/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using Umbraco.Core.CodeAnnotations;
@@ -9,7 +10,8 @@ namespace Umbraco.Core.Models
///
public static class UmbracoObjectTypesExtensions
{
- private static readonly Dictionary UmbracoObjectTypeCache = new Dictionary();
+ //MUST be concurrent to avoid thread collisions!
+ private static readonly ConcurrentDictionary UmbracoObjectTypeCache = new ConcurrentDictionary();
///
/// Get an UmbracoObjectTypes value from it's name
@@ -48,24 +50,22 @@ namespace Umbraco.Core.Models
/// a GUID value of the UmbracoObjectTypes
public static Guid GetGuid(this UmbracoObjectTypes umbracoObjectType)
{
- if (UmbracoObjectTypeCache.ContainsKey(umbracoObjectType))
- return UmbracoObjectTypeCache[umbracoObjectType];
+ return UmbracoObjectTypeCache.GetOrAdd(umbracoObjectType, types =>
+ {
+ var type = typeof(UmbracoObjectTypes);
+ var memInfo = type.GetMember(umbracoObjectType.ToString());
+ var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
+ false);
- var type = typeof(UmbracoObjectTypes);
- var memInfo = type.GetMember(umbracoObjectType.ToString());
- var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
- false);
+ if (attributes.Length == 0)
+ return Guid.Empty;
- if (attributes.Length == 0)
- return Guid.Empty;
+ var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
+ if (attribute == null)
+ return Guid.Empty;
- var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
- if (attribute == null)
- return Guid.Empty;
-
- UmbracoObjectTypeCache.Add(umbracoObjectType, attribute.ObjectId);
-
- return attribute.ObjectId;
+ return attribute.ObjectId;
+ });
}
///
diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
index 522e0b4173..98d5d9cebc 100644
--- a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
+++ b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence
/// can then override any additional execution (such as additional loggging, functionality, etc...) that we need to without breaking compatibility since we'll always be exposing
/// this object instead of the base PetaPoco database object.
///
- public class UmbracoDatabase : Database
+ public class UmbracoDatabase : Database, IDisposeOnRequestEnd
{
private readonly Guid _instanceId = Guid.NewGuid();
///
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 2cc6a8fbd4..dc95d29ab4 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -166,6 +166,7 @@
+
diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs
index 17751b4077..2458dc62e0 100644
--- a/src/Umbraco.Web/UmbracoContext.cs
+++ b/src/Umbraco.Web/UmbracoContext.cs
@@ -24,7 +24,7 @@ namespace Umbraco.Web
///
/// Class that encapsulates Umbraco information of a specific HTTP request
///
- public class UmbracoContext : DisposableObject
+ public class UmbracoContext : DisposableObject, IDisposeOnRequestEnd
{
private const string HttpContextItemName = "Umbraco.Web.UmbracoContext";
private static readonly object Locker = new object();
diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs
index 79f029c4a7..5ba568c56e 100644
--- a/src/Umbraco.Web/UmbracoModule.cs
+++ b/src/Umbraco.Web/UmbracoModule.cs
@@ -467,11 +467,15 @@ namespace Umbraco.Web
///
private static void DisposeHttpContextItems(HttpContext http)
{
+ // do not process if client-side request
+ if (http.Request.Url.IsClientSideRequest())
+ return;
+
//get a list of keys to dispose
var keys = new HashSet