HttpContext.Current.Items的替代品

时间:2017-02-13 09:29:37

标签: c# asp.net static thread-safety httpcontext

最近,我在我们的系统中发现了一个错误,共享了一个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和/或exe。我愿意使用分支逻辑来确定在必要时触及哪个属性,只要我只需要更改此属性(显然,两者的解决方案都是首选。

1 个答案:

答案 0 :(得分:1)

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

Scott Hanselman撰写了关于ThreadStatic使用的Blog Post。特别是,这部分是相关的:

  

当您在ASP.NET中操作时,不要在静态成员上拍一个[ThreadStatic]属性,因为您可能无法控制线程生命...您继承了一个工作线程。 ThreadStatic为您提供线程本地存储,而不是HttpContext本地存储!

基本上,因为(IIS)Worker倾向于重用App Pool中的线程,所以通常不建议将此属性用于Web进程。

为了应用这一点,同时仍然保持Web请求的线程安全性(并且只触及属性),您可以使用分支逻辑来确定从哪个部分存储/检索数据:

[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;
    }
}