Archive

Archive for July, 2015

Xbap (ClickOnce): The underlying connection was closed: An unexpected error occurred on a send


Last week after deploying to one of one of the internal environments, we got the following error on the installation of an xbap application

An exception occurred while downloading the manifest. Following failure messages were detected:

+ Downloading https://<url>/app.xbap did not succeed.

+ The underlying connection was closed: An unexpected error occurred on a send.

+ Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

+ An existing connection was forcibly closed by the remote host

It turned out that the IT group had disabled TLS 1.0 and 1.1. After enabling those protocols, the xbap was operating as expected

Categories: Uncategorized

Performance tip – Caching expiry in web applications


Caching data that rarely change can give you a big performance boost especially if it takes time to fetch and/or calculate that data. In .NET 4.0, Microsoft introduced the .NET Memory Cache which is a thread safe cache that can be used Windows and Web applications. For more information about the MemoryCache class you can visit https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx

While I was doing a load test for web application for one of my clients, I noticed that the Queued Requests performance counter goes up every five minutes. By using a code profiler, it showed that there were many calls to refresh some of the cached data. Taking a closer look at the code below, if user 1 executing line (value = service.GetStreets();) while the other users are checking if value is cached, there is a potential of thousands of requests to fetch the same data especially if that data is frequently used.

We were using a CacheWrapper that applies a cache policy based on the cache name. With the CacheWrapper we can write the code to cache the Street Streets as follows:


public List<Street> GetStreets()
{

var value = CacheWrapper.Get(CacheNames.Streets) as List<Street>;

if (value == null)
{

    value = service.GetStreet();
    CacheWrapper.Set(CacheNames.Streets, value);

}

return value;

}

My first approach was to use a lock and double check the value


bool StreetsDataInitialized = false;
Object StreetsLock = new Object();

public List<Street> GetStreets()
{

var value = CacheWrapper.Get(CacheNames.Streets) as List<Street>;

if (value == null)
{
StreetsDataInitialized = false;

lock (StreetsLock)
 {
 if (StreetsDataInitialized)
 {
    return CacheWrapper.Get(CacheNames.Streets) as List<Street>;
 }

 value = service.GetStreets();
 CacheWrapper.Set(CacheNames.Streets, value);
 StreetsDataInitialized = true;

}

}

return value;

}

But there were many values that need to be cached and refreshed and I didn’t want to create two variables per cached value. I came up with a more generic way to achieve my goal. I started with the CacheLock Class

 public class CacheLock
  {
     public bool Initialized { get; set; }
     public object LockObject = new object();

 }

I used the ConcurrentDictionary to store the locks. I also created a generic GetOrSetCacheValue function which gets or creates a CacheLock for each cached data and invoke “function” if the data is not cached.


Public class CacheableLookupProvider
{
private static ConcurrentDictionary<string, CacheLock> LockDictionary = new ConcurrentDictionary<string, CacheLock>();
private readonly IStreetsService service;

Public CacheableStreetsProvider(IStreetsService service)
{
    this.service = service;
}

 private T GetOrSetCachedValue<T>(string cacheName, Func<T> function) where T : class
 {
    var value = CacheWrapper.Get(cacheName) as T;
    if (value == null)
     {
       var lockObject = LockDictionary.GetOrAdd(cacheName, new CacheLock());
       lockObject.Initialized = false;
      
      lock (lockObject.LockObject)
       {
         if (lockObject.Initialized)
         {
           return CacheWrapper.Get(cacheName) as T;
         }
         value = function();
         CacheWrapper.Set(cacheName, value);
         lockObject.Initialized = true;
       }
    }
    return value;
 }

 public List<Street> GetStreets ()
 {
    return GetOrSetCachedValue(CacheNames.Streets, () => service.GetStreets());
 }

 public List<Province> GetProvinces ()
 {
   return GetOrSetCachedValue(CacheNames.Provinces, () => service. GetProvinces());
 }

}

Categories: asp.net Tags: , , ,