ASP.net HttpContext.Current异步任务。项目是空的-如何处理这个?

时间:2022-04-19 02:23:06

We are running a very large web application in asp.net MVC .NET 4.0. Recently we had an audit done and the performance team says that there were a lot of null reference exceptions.

我们正在asp.net MVC。4.0中运行一个非常大的web应用程序。最近我们进行了一次审计,性能团队说有很多空引用异常。

So I started investigating it from the dumps and event viewer. My understanding was as follows:

所以我开始从转储和事件查看器中研究它。我的理解如下:

We are using Asyn Tasks in our controllers. We rely on HttpContext.Current.Items hashtable to store a lot of Application level values.

我们在控制器中使用Asyn任务。我们依靠HttpContext.Current。Items hashtable用于存储许多应用程序级别的值。

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 onto the new thread that is spawned from Task factory. This context.Items is used again in the thread wherever necessary. Say for ex:

因此,我们将上下文对象复制到从Task factory生成的新线程上。这个上下文。只要有必要,在线程中再次使用项。对前女友说:

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

This runs fine as long as number of parallel requests are optimal. My questions are as follows:

只要并行请求的数量是最优的,这就可以很好地运行。我的问题如下:

1. When the load is more and there are too many parallel requests, I notice that HttpContext.Current.Items is empty. I am not able to figure out a reason for this and this causes all the null reference exceptions.

1。当负载更大且有太多并行请求时,我注意到HttpContext.Current。项目是空的。我无法找出原因,这会导致所有的空引用异常。

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

2。如何确保它不是null ?有什么办法吗?

NOTE: I read through in * and people have questions like HttpContext.Current is null - but in my case it is not null and its empty. I was reading one more article where the author says that sometimes request object is terminated and it may cause problems since dispose is already called on objects. I am doing a copy of Context object - its just a shallow copy and not a deep copy.

注意:我在*中浏览了一遍,人们有像HttpContext这样的问题。Current是空的——但是在我的例子中,它不是空的。我又读了一篇文章,作者说有时候请求对象会被终止,这可能会导致问题,因为对对象已经调用了dispose。我正在做一个Context对象的拷贝——它只是一个浅拷贝而不是一个深拷贝。

2 个解决方案

#1


2  

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

您的问题是HttpContext的实例成员不是线程安全的:

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

这种类型的任何公共静态(在Visual Basic*享)成员都是线程安全的。任何实例成员都不能保证是线程安全的。

When accessing it the way you are doing (multiple threads) you need to do your own synchronization.

当您使用(多线程)访问它时,您需要进行自己的同步。

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

MSDN:system.web.httpcontext

#2


0  

Maybe I'm misreading this, but I'm getting the impression that you're only trying to prevent the 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;
        }
    }
}

#1


2  

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

您的问题是HttpContext的实例成员不是线程安全的:

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

这种类型的任何公共静态(在Visual Basic*享)成员都是线程安全的。任何实例成员都不能保证是线程安全的。

When accessing it the way you are doing (multiple threads) you need to do your own synchronization.

当您使用(多线程)访问它时,您需要进行自己的同步。

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

MSDN:system.web.httpcontext

#2


0  

Maybe I'm misreading this, but I'm getting the impression that you're only trying to prevent the 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;
        }
    }
}