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