gpt4 book ai didi

c# - ResourceStrings 真的被缓存了吗?

转载 作者:行者123 更新时间:2023-11-30 20:02:59 27 4
gpt4 key购买 nike

所有,不久前(当我被冲昏了头脑时)我问了以下问题 Performace Overheads when Using Resource Files (.resx)关于使用资源字符串的性能开销。我得到了一个赞成的答案,并认为答案是正确的。然而,之前,我正在本地化在错误情况下调用的消息字符串,而不是性能关键 - 现在我被要求对我们的代码“强大的”(大量性能关键代码、嵌入式循环等)实现本地化。

有一些时间来更详细地研究这个,我注意到调用像

这样的资源
Resources.MessageStrings.SomeResourceName

仅引用对自动生成的代码 MessageStrings.Designer.cs 的调用,它使用

internal static string SomeResourceName {
get {
return ResourceManager.GetString("SomeResourceName", resourceCulture);}
}

所以深入挖掘,我想我会反编译在

中找到的 ResourceManager

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5\mscorlib.dll

查看 GetString() 正在做什么 [它真的在缓存我的资源字符串吗?]。反编译,我发现

[__DynamicallyInvokable]
public virtual string GetString(string name, CultureInfo culture)
{
if (name == null)
throw new ArgumentNullException("name");
if (ResourceManager.s_IsAppXModel && object.ReferenceEquals((object) culture, (object) CultureInfo.CurrentUICulture))
culture = (CultureInfo) null;
if (this._bUsingModernResourceManagement)
{
if (this._PRIonAppXInitialized)
return this.GetStringFromPRI(name, culture == null ? (string) null : culture.Name, this._neutralResourcesCulture.Name);
if (this._PRIExceptionInfo == null || this._PRIExceptionInfo._PackageSimpleName == null || this._PRIExceptionInfo._ResWFile == null)
throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_NoPRIresources"));
throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_ResWFileNotLoaded", (object) this._PRIExceptionInfo._ResWFile, (object) this._PRIExceptionInfo._PackageSimpleName));
}
else
{
if (culture == null)
culture = Thread.CurrentThread.GetCurrentUICultureNoAppX();
if (FrameworkEventSource.IsInitialized)
FrameworkEventSource.Log.ResourceManagerLookupStarted(this.BaseNameField, this.MainAssembly, culture.Name);
ResourceSet resourceSet1 = this.GetFirstResourceSet(culture);
if (resourceSet1 != null)
{
string @string = resourceSet1.GetString(name, this._ignoreCase);
if (@string != null)
return @string;
}
foreach (CultureInfo culture1 in new ResourceFallbackManager(culture, this._neutralResourcesCulture, true))
{
ResourceSet resourceSet2 = this.InternalGetResourceSet(culture1, true, true);
if (resourceSet2 != null)
{
if (resourceSet2 != resourceSet1)
{
string @string = resourceSet2.GetString(name, this._ignoreCase);
if (@string != null)
{
if (this._lastUsedResourceCache != null)
{
lock (this._lastUsedResourceCache)
{
this._lastUsedResourceCache.lastCultureName = culture1.Name;
this._lastUsedResourceCache.lastResourceSet = resourceSet2;
}
}
return @string;
}
else
resourceSet1 = resourceSet2;
}
}
else
break;
}
if (FrameworkEventSource.IsInitialized)
FrameworkEventSource.Log.ResourceManagerLookupFailed(this.BaseNameField, this.MainAssembly, culture.Name);
return (string) null;
}
}

上面的代码没有任何迹象表明它正在“缓存”我的字符串(在这个词的典型/最真实的意义上),它似乎在进行某种类型的复杂查找。我注意到该方法正在使用未记录的 __DynamicallyInvokable 属性,并发现 Hans ( What is the __DynamicallyInvokable attribute for? ) 对该属性的简短讨论。

我的问题是:对于性能关键代码,我能否依赖足够快的 ResourceManager(它会缓存我的字符串吗?),还是我需要自己预处理和缓存资源字符串?

感谢您的宝贵时间。

最佳答案

资源被缓存。如果您通过资源管理器跟踪调用堆栈,它是这样的:1.

[System.Security.SecuritySafeCritical]  // auto-generated 
public virtual String GetString(String name, CultureInfo culture) {
//...
String value = rs.GetString(name, _ignoreCase);
//...
}

2.

public virtual string GetString(string name, bool ignoreCase)
{
object objectInternal = this.GetObjectInternal(name);
//...
}

3.

private object GetObjectInternal(string name)
{
//...
Hashtable hashtable = this.Table;
//...
return hashtable[(object) name];
}

因此此时从哈希表中读取值。

一旦资源文件被访问,哈希表就会被填充:

构造函数:

[SecuritySafeCritical]
public ResourceSet(string fileName)
{
this.Reader = (IResourceReader) new ResourceReader(fileName);
this.CommonInit();
this.ReadResources();
}

和 ReadResources:

protected virtual void ReadResources()
{
IDictionaryEnumerator enumerator = this.Reader.GetEnumerator();
while (enumerator.MoveNext())
{
object obj = enumerator.Value;
this.Table.Add(enumerator.Key, obj);
}
}

关于c# - ResourceStrings 真的被缓存了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15928233/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com