【问题标题】:Alternative to HttpContext.Current.Items替代 HttpContext.Current.Items
【发布时间】:2017-02-13 09:29:36
【问题描述】:

最近,我在我们的系统中发现了一个错误,即共享 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。如有必要,我愿意使用分支逻辑来确定要命中的属性,只要我只需要更改此属性即可(显然,首选一种解决方案。

【问题讨论】:

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


【解决方案1】:

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

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

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

基本上,由于 (IIS) Worker 倾向于重用应用程序池中的线程,因此通常不建议将此属性用于 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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多