C# 重新访问静态vs成员字段,需要建议

C# 重新访问静态vs成员字段,需要建议,c#,asp.net,C#,Asp.net,我需要一个关于我应该实现的功能的建议。这个场景是我们没有一个HttpHandler来拦截文件上传。在处理程序中,我需要在内存中保存一个大型字符串字典。这本词典可能有100个词条之多。我想知道将其存储在静态变量中是否安全,这样就不会在每次创建处理程序实例时初始化它(肯定会有很多实例)。一般来说,在这种情况下采取什么方法。使用静态字段来保存不会更改的数据,这通常是一个更好的主意吗?IMHO一个静态字段就可以了。您可以在第一次使用时初始化它。只需确保您正在使用线程同步。 您也可以使用单例,但我认为,这

我需要一个关于我应该实现的功能的建议。这个场景是我们没有一个HttpHandler来拦截文件上传。在处理程序中,我需要在内存中保存一个大型字符串字典。这本词典可能有100个词条之多。我想知道将其存储在静态变量中是否安全,这样就不会在每次创建处理程序实例时初始化它(肯定会有很多实例)。一般来说,在这种情况下采取什么方法。使用静态字段来保存不会更改的数据,这通常是一个更好的主意吗?

IMHO一个静态字段就可以了。您可以在第一次使用时初始化它。只需确保您正在使用线程同步。

您也可以使用单例,但我认为,这有点过头了…

您可以覆盖
HttpHandler.IsReusable
并返回
false
,以避免每次都重新创建处理程序。然后可以将字典存储在本地成员中

否则,您需要使用静态变量


你的字典似乎不大——100条词条简直是小菜一碟。除非每根线都有几兆欧长。

这是一个很好的解决方案。在应用程序启动时初始化字典(例如Global.asax),然后就可以从中读取字典了。

100个字典中的项目并不是很大,事实上,这还不到哈希比线性搜索快的程度。如果初始化后它将永远不会更改,那么static可能会工作-就我个人而言,我尝试在
static
和instance之间进行一些其他抽象-例如,我可以传递到所有需要它的实例中的“context”或“configuration”类。然后我可以有多个并行配置(如果需要),但是所有相关的实例都可以共享一个上下文/配置-因此没有重复。

如果您的字典对所有实例都相同,请使用静态字段,否则请使用属性字段


如果您的数据不会更改,则使用只读变量

您的意思是静态属性与静态字段?我可以问一下,您在本词典中有哪些内容,这些数据来自哪里?鉴于文件上传速度通常非常慢,这里不需要高性能。字典将包含映射到扩展名的mime类型。我需要手动设置上传文件的内容类型,因为从Silverlight/Flash上传的文件总是带有Application/octet stream的内容类型,这是不可接受的。所以你真的不需要缓存整个列表。简单地得到你需要的(我猜,基于文件扩展名)。您可以将内存用于其他更重要的情况,而在这种情况下,您只需从数据库中获取数据即可。@Genady,请记住,从技术上讲,内存中可能有多个词典副本(在这种情况下,这是一种浪费)。原因(对于多个副本)是,在应用程序池的流程模型中,如果您将MaxWorkerProcess设置为1以上(在本例中,您通常会这样做,因为文件上载需要时间,并且您需要额外的流程来处理其他类型的请求),然后,每个工作进程将位于不同的应用程序域中,因此服务器计算机上会存在使用更多内存的静态字典的多个副本。这种方法的问题是,将创建(最终)多个实例,每个实例都需要初始化自己的副本。不仅如此,由于te处理程序是可重用的,内存中现在还会有多个副本。等等,你的意思是“不是真的非常大”?这些项永远不会改变,它们基本上是内容类型/扩展对,它们是预定义的,将来不太可能改变。谢谢你的反馈,我将坚持静态场方法。我想你可能想修改第一句话,它没有意义;“字典里的100个条目真的很大”@massif@DoctaJonez-是的,对不起;反转失败readonly在这里有什么帮助?在这种情况下,readonly仅仅意味着字典本身不能设置为另一个实例。它不阻止修改现有词典中的项。在这种情况下,如果它们被修改,并且字段是静态的,OP将需要同步从附加项读取/添加到附加项。