diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs index 542d4b769..1f768bce0 100644 --- a/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Reflection; using Microsoft.ApplicationServer.Caching; using Orchard.Azure.Services.Environment.Configuration; using Orchard.Caching; @@ -122,12 +123,27 @@ namespace Orchard.Azure.Services.Caching.Output { return function.Invoke(); } catch (DataCacheException) { - DataCacheFactory cacheFactory; - Logger.Debug("Retrying cache operation"); - if (_dataCacheFactories.TryRemove(CacheConfiguration, out cacheFactory)) { - cacheFactory.Dispose(); + // applying http://blogs.msdn.com/b/cie/archive/2014/04/29/cache-retry-fails-what-next.aspx + try { + DataCacheFactory cacheFactory; + Logger.Debug("Retrying cache operation"); + if (_dataCacheFactories.TryRemove(CacheConfiguration, out cacheFactory)) { + lock (_dataCacheFactories) { + cacheFactory.Dispose(); + // Clear DataCacheFactory._connectionPool + var coreAssembly = typeof(DataCacheItem).Assembly; + var simpleSendReceiveModulePoolType = coreAssembly. + GetType("Microsoft.ApplicationServer.Caching.SimpleSendReceiveModulePool", throwOnError: true); + var connectionPoolField = typeof(DataCacheFactory).GetField("_connectionPool", BindingFlags.Static | BindingFlags.NonPublic); + connectionPoolField.SetValue(null, Activator.CreateInstance(simpleSendReceiveModulePoolType)); + } + } + return Retry(function, times--); + } + catch (Exception e) { + Logger.Error(e, "An unexpected error occured while releasing a DataCacheFactory."); + return default(T); } - return Retry(function, times--); } }