Async task ASP.net HttpContext.Current.Items is empty - how to deal with this?

We are using a very large web application in asp.net MVC.NET 4.0. We recently conducted an audit and the development team reported that there were many null reference exceptions.

So, I started to research it from dumps and event viewer. My understanding was as follows:

We are using Asyn Tasks in our controllers. We rely on the HttpContext.Current.Items hash table to store multiple application-level values.

Task<Articles>.Factory.StartNew(() =>
        {
            System.Web.HttpContext.Current = ControllerContext.HttpContext.ApplicationInstance.Context;
            var service = new ArticlesService(page);
            return service.GetArticles();
        }).ContinueWith(t => SetResult(t, "articles"));

      

So we are copying the context object to a new thread created from the Task factory. This context. Items are reused in the flow where needed. Let's say for example:

public class SomeClass
  {
    internal static int StreamID
    {
        get
        {
            if (HttpContext.Current != null)
            {
                return (int)HttpContext.Current.Items["StreamID"];
            }
            else
            {
                return DEFAULT_STREAM_ID;
            }
        }
    }

      

This works fine as long as the number of parallel requests is optimal. My questions are:

1. When there are more downloads and too many parallel requests, I noticed that HttpContext.Current.Items is empty. I can't figure out the reason for this and it throws all null referenced exceptions.

2. How do we make sure it's not null? Any workaround if present?

NOTE. I read on StackOverflow and people have questions like HttpContext.Current is null, but in my case it is not empty and empty. I read another article in which the author says that sometimes the request for an object is aborted and this can cause problems since dispose is already called by the objects. I am making a copy of the Context object - it is only a shallow copy, not a deep copy.

+3


source to share


2 answers


Your problem is that the members of the HttpContext instance are not thread safe:

All public static (Shared in Visual Basic) members of this type are thread safe. Any members of the instance are not guaranteed to be safe streams.

When accessing it like you do (multiple threads), you need to do your own sync.



static object locker = new object();
get
{
    lock (locker)
    {
        if (HttpContext.Current != null)
        {
            return (int)HttpContext.Current.Items["StreamID"];
        }
        else
        {
            return DEFAULT_STREAM_ID;
        }
    }
}

      

MSDN: system.web.httpcontext

+2


source


I may be misunderstanding this, but I am under the impression that you are trying to prevent a null reference error.



public class SomeClass
{
    internal static int StreamID
    {
        get
        {
            int returnValue;
            if (HttpContext.Current != null)
            {
                if(HttpContext.Current.Items["StreamID"] != null)
                {
                    returnValue = (int)HttpContext.Current.Items["StreamID"];
                }
                else
                {
                    returnValue = DEFAULT_STREAM_ID;
                }  
            }
            else
            {
                returnValue = DEFAULT_STREAM_ID;
            }
            return returnValue;
        }
    }
}

      

0


source







All Articles