替代 HttpContext.Current.Items

Alternative to HttpContext.Current.Items

最近,我在我们的系统中发现了一个错误,其中共享了 dll 中的 属性。在 ASP.Net 的情况下,这会导致线程安全问题。

protected static object Data { get; set; }

为了以尽可能小的更改解决此问题,我换出了内部 属性 以利用 HttpContext.Current.Items 来存储和检索值。这适用于我们的网站。

protected static object Data
{
    get
    {
        return HttpContext.Current.Items[DataKey] as object;
    }
    set
    {
        HttpContext.Current.Items[DataKey] = value;
    }
}

但是,我们还有一个引用此 dll 的 exe。当它运行时(显然)没有对 HttpContext.Current.

的引用

是否有我可以使用的替代对象,它适用于 asp.net and/or exe。如果有必要,我愿意使用分支逻辑来确定要命中哪个 属性,只要我只需要更改此 属性(显然,两者的解决方案是首选。

因此 [ThreadStatic] 属性在这种情况下可能会有所帮助,但它附带警告。

Scott Hanselman 写了一篇关于 ThreadStatic 的文章 Blog Post。特别是,这部分是相关的:

Don't slap a [ThreadStatic] attribute on a static member when you're operating within ASP.NET as chances are you don't control the thread life...you inherit a worker thread. ThreadStatic gives you thread local storage, not HttpContext local storage!

基本上,由于 (IIS) Worker 倾向于从应用程序池中 re-use 个线程,因此通常不建议将此属性用于 Web 进程。

为了应用它,同时仍然保持 Web 请求的线程安全(并且只触及 属性),您可以使用分支逻辑来确定 store/retrieve 您的数据的哪些部分来自:

[ThreadStatic]
private static object _data;

protected static object Data
{
    get
    {
        if (HttpContext.Current != null)
            return HttpContext.Current.Items[DataKey] as object;
        else
            return _data;
    }
    set
    {
        if (HttpContext.Current != null)
            HttpContext.Current.Items[DataKey] = value;
        else
            _data = value;
    }
}