【问题标题】:Performance Overheads when Using Resource Files (.resx)使用资源文件 (.resx) 时的性能开销
【发布时间】:2013-03-09 09:49:08
【问题描述】:

注意,我知道有关此主题的以下问题:

  1. Are there any performance issues or caveats with resource (.resx) files?

  2. Are string resources (.resx) properties kept in memory?

等。但是,我在这些问题中没有找到任何令人满意的答案(它们不够具体)。

我也知道有关此主题的 MSDN 页面,但这些页面似乎也忽略了有关使用资源文件开销的技术信息。


我的困境是我们即将着手本地化一个相当大的 WinForms 应用程序。在这个阶段,我关心的是从嵌套循环中访问 .resx 文件中的资源的性能。目前,对于我们本地化的一小部分代码(DataGridView 等的列名、行标题等),我们正在将相关类的全局变量中的资源兑现并使用它们。

如何访问来自 .resx 的资源(它们是否在编译时包含在程序集中?)以及通过兑现这些资源和使用全局变量进行访问是否有性能优势?

【问题讨论】:

    标签: c# winforms resources resx


    【解决方案1】:

    字符串资源缓存在内存中。查看"Resources.Designer.cs"中生成的代码。

    它使用System.Resources.ResourceManager,它会缓存字符串。

    另请注意this ResourceManager constructor。它提到您可以更改缓存策略:

    此构造函数使用系统提供的 ResourceSet 实现。 要使用自定义资源文件格式,您应该从 ResourceSet 类,重写 GetDefaultReader 和 GetDefaultWriter 方法,并将该类型传递给 ResourceManager(String, Assembly, 类型)构造函数。使用自定义 ResourceSet 可能对 控制资源缓存策略或支持您自己的资源 文件格式,但一般不需要。

    (我的重点)

    documentation for ResourceSet 明确表示:

    ResourceSet 类枚举 IResourceReader,加载每个名称和值,并将它们存储在 Hashtable 中

    所以我们确实知道默认情况下您将获得的确切缓存策略。

    [编辑] 既然你似乎不相信我! :)

    (1) 查看构造函数ResourceManager(string baseName,Assembly assembly) 的文档。它指出:

    此构造函数使用系统提供的 ResourceSet 实现。

    (2) 现在查看documentation for ResourceSet。它指出:

    ResourceSet 类枚举 IResourceReader,加载每个名称和值,并将它们存储在 Hashtable 中。

    因此,这种缓存行为确实记录在 MSDN 中,此外,您可以通过使用 Resharper 检查实现来验证这是否正在发生。

    【讨论】:

    • +1 非常感谢您的回复。最欣赏。你能为我解释另一件事吗?要从MSDN docs 调用资源,我们使用ResourceManager rm = new ResourceManager("ExampleResources", typeof(Example).Assembly); string greeting = rm.GetString("Greeting");,但我从stackoverflow.com/a/1142840/626442 了解到,这也可以通过Console.WriteLine(strings.Hello); 来完成,其中资源文件为strings.resx。有什么区别?
    • 你能帮忙解决这个问题吗:stackoverflow.com/questions/15523604/…
    • 使用strings.Hello只是使用Resources.Designer.cs中自动生成的类
    • 我仍然不确定字符串的缓存。如果您查看 Design.cs 文件,给定资源的属性调用GetString(...),这对我来说似乎不是缓存字符串,而是在运行时从资源文件中检索它们......此外,MSDN docs不要提及缓存。
    • 它调用ResourceManager.GetString() 最终调用ResourceSet.GetString() 调用ResourceSet.GetObjectInternal() 在哈希表中查找字符串。您可以通过检查 Resharper 中的代码来验证这一点。 MSDN 文档确实提到了缓存,我在上面的回答中提供了引用。
    猜你喜欢
    • 2016-09-09
    • 2013-03-02
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多