我的代码:

System.Resources.ResourceManager resourceManager = GetResourceManager();
string str = resourceManager.GetString("delete", new CultureInfo(1033));

在当前的项目中,根据.NET 2.0编译,所有内容均可用除外。多变的 str 包含用于LCID 1033-的资源字符串 - 删除, , 还行吧。

我们现在正在升级到.NET 4.0,在目标框架.NET 4.0下重新编译了项目。现在编译为.NET 4.0组件,它引发了异常 System.ArgumentNullexception 带有消息 值不能为null。。堆栈跟踪:

   at System.Threading.Monitor.Enter(Object obj)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)

有趣的是StackTrace,它指向内部框架方法 ResourceManager.internalgetResourceset 这会导致打电话 Monitor.enter 使用null对象。但是我叫方法 Getstring 没有null参数 getString(“删除”,新cultureinfo(1033)).

这个错误似乎与 system.ArgumentNullexception in System.Threading.Monitor.enter. 。也许在Monitor.enter中或其他错误?

更新:当我在调试器上查看对象时 resourceManager.ResourceSets.Items[2].Value.Table["delete"] 然后它包含字符串值“ delete”。属性项目[2]指向LCID 1033.这意味着资源管理器已经包含资源密钥的本地化字符串 删除 语言 1033. 。有人知道哪里可能是错误吗?

有帮助吗?

解决方案

我还认为您应该声明并使用自己的字典作为存储

其他提示

我发现自己答案。以下是详细信息:我们有这样的自定义实现资源管理器:

public class DatabaseResourceManager : System.Resources.ResourceManager 
{
  public DatabaseResourceManager(int applicationID, string bundle) 
  {
    foreach (int languageID in ResourceProvider.Provider.GetLanguages(applicationID))
    {
      DatabaseResourceReader r = new DatabaseResourceReader(applicationID, bundle, languageID);
      ResourceSets.Add(new CultureInfo(languageID), new ResourceSet(r));
    }
}

在.NET 2.0中,它运行良好,但是在.NET 4.0中,在ResourceManager的实现中发生了变化。我认为该问题是在.NET 2.0中实例化私有字段中的无参数构造函数 this._resourcesets (后来使用 InternalGetResourceset 用于Monitor.enter)。但是.NET 4.0无参数构造函数不能实例化私有字段 this._resourcesets 因此,它以后失败(如Abobe所述)。

我必须重写我的自定义资源经理以解决:

public class DatabaseResourceManager : System.Resources.ResourceManager 
{
  public DatabaseResourceManager(int applicationID, string bundle) 
  {
    ResourceSets = new Hashtable();
    this.applicationID = applicationID;
    this.bundle = bundle;
  }

  protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
  {
    if (this.ResourceSets.Contains(culture.Name))
        return this.ResourceSets[culture.Name] as ResourceSet;

    lock (syncLock)
    {
        if (this.ResourceSets.Contains(culture.Name))
            return this.ResourceSets[culture.Name] as ResourceSet;

        DatabaseResourceReader r = new DatabaseResourceReader(applicationID, bundle, culture.LCID);
        ResourceSet rs = new ResourceSet(r);

        this.ResourceSets.Add(culture.Name, rs);

        return rs;
    }
  }
}

“魔术”这是我必须覆盖方法 InternalGetResourceset 从自定义存储(DB)加载我的资源,然后返回“资源集”以进行指定文化。现在它就像魅力一样。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top