HttpContext的跨线程 [英] HTTPContext across threads

查看:332
本文介绍了HttpContext的跨线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要实例每个Web请求的单独的对象,从而使数据被处理一次,是有效的整个要求,我是用 HttpContext.Current.Items 来HTTP请求中共享数据,一切都很正常,直到我们需要在 singleton对象在多个线程实例,我想出的第一件事就是到HttpContext实例传递给新的线程:

  HttpContext的背景下= HttpContext.Current;
ThreadPool.QueueUserWorkItem(回调=>
    {
        HttpContext.Current =背景;
        //等等等等
    });

我不认为这是一个线程安全的方法,因为注意到这里

使用反射器我想通HttpContext.Current.Items实际使用的在每个逻辑线程Cal​​lContext中以存储对象。所以我改变了单接口,这样的:

 公共静态SingletonType SingletonInstance
{
    {返回CallContext.GetData(Key)作为SingletonType; }
    集合{CallContext.SetData(键,值); }
}

和简单地覆盖 SingletonInstance 开始任何新线程的时候!在code正常工作,但似乎在某种程度上重负载下,CallContext.GetData(键)返回null,应用程序崩溃与一个空引用异常!

我在想,如果 CallContext.GetData 是原子?但它只是看起来不正确的CallContext中是线程特定的数据存储,并且必须是原子或我错过了点!

我的另一个猜测是,设置SingletonInstance(CallContext.SetData)在一个线程中发生,而CallContext.GetData在另一个执行作为指出这里但我不知道如何/为什么?

更新:

我们都保持在服务器上的一个阵列,每个在线用户的一个实例。单例对象实际上是重新presenting当前用户的对象的引用。当前用户必须在每个线程的数据库查询,日志,错误处理和更独特的和可用的,这是它是如何做的:

 公共静态ApplicationUser的currentUser
{
    {返回CallContext.GetData(ApplicationUser)作为ApplicationUser; }
    集合{CallContext.SetData(ApplicationUser,值); }
}


解决方案

如果它的负载下ASP.NET可能会迁移线程之间的请求。一旦收到请求页面的构造可以执行对另一个一个线程和网页加载。在此线程切换CallContext中和ThreadStatic不迁移,但luckaly HttpContext的是。

为HttpContext的是呼叫上下文,但是这是在ASP.NET有点怪癖,可能是由于偷工减料,以提高性能,这可能会产生误导。

您必须通过删除依赖关系CallContext中,并使用HttpContext的整个生活方式。

您可以阅读此了不起的博客文章通过Piers7。

I need to instantiate a singleton object per web request, so that the data is processed once and is valid throughout the request, I was using HttpContext.Current.Items to share data during HTTP request, everything was fine until we needed the singleton object instance across multiple threads, the first thing that I came up with was to pass the HttpContext instance to the new thread:

HttpContext context = HttpContext.Current;
ThreadPool.QueueUserWorkItem(callback =>
    {
        HttpContext.Current = context;
        // blah blah
    });

Which I don't think is a thread-safe approach as noted here.

Using Reflector I figured HttpContext.Current.Items actually uses CallContext to store objects in each logical thread. So I changed the singleton interface to this:

public static SingletonType SingletonInstance
{
    get { return CallContext.GetData(key) as SingletonType; }
    set { CallContext.SetData(key, value); }
}

And simply overwrite SingletonInstance when starting any new thread! The code works fine, however it seems that somehow under heavy load, CallContext.GetData(key) returns null and the application crashes with with a null reference exception!

I was thinking, if CallContext.GetData is atomic? But it just doesn't seem right, the CallContext is thread specific data storage and must be atomic or I am missing the point!

My other guess is that setting the SingletonInstance (CallContext.SetData) happens in one thread while CallContext.GetData executes in another as noted here but I don't know how/why?

update:

We are keeping an instance of each online user in an array on the server. The singleton object is actually a reference to the object representing current user. Current user must be unique and available in each thread for database querying, logging, error handling and more, this is how it is done:

public static ApplicationUser CurrentUser
{
    get { return CallContext.GetData("ApplicationUser") as ApplicationUser ; }
    set { CallContext.SetData("ApplicationUser", value); }
}

解决方案

ASP.NET may migrate request between threads if it's under load. Once request is received page constructor may execute on one thread and page load on another. In this thread switch CallContext and ThreadStatic are not migrated, but luckaly HttpContext is.

This may be misleading as HttpContext is call context, but this is a little quirk in ASP.NET, probably due to cutting corners to improve performance.

You'll have to remove dependencies to CallContext and use HttpContext entire way through.

You can read more details in this terrific blog post by Piers7.

这篇关于HttpContext的跨线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆