Question

Mon code:

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

Dans projet en cours compilé sous fonctionne tout .NET 2.0 comme exceptés. Variable str contient la chaîne de ressources pour LCID 1033 -. Supprimer , c'est ok

Nous améliorons maintenant .NET 4.0, projet recompilé dans le cadre cible .NET 4.0. Maintenant, compilé sous forme d'ensembles .NET 4.0, il émet une exception System.ArgumentNullException avec le message La valeur ne peut être nulle trace .Stack:.

   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)

Intéressant ici est stacktrace, où il pointe à la méthode du cadre interne ResourceManager.InternalGetResourceSet qui provoque à l'appel Monitor.Enter avec l'objet null. Mais j'appelle méthode GetString avec pas de paramètres nuls GetString ( "delete", nouvelle CultureInfo (1033)) .

Ce bug semble être similaire à System.ArgumentNullException dans System.Threading. Monitor.Enter . Peut-être un bogue dans Monitor.Enter, ou autre chose?

Mise à jour: Quand je regarde dans débogueur resourceManager.ResourceSets.Items[2].Value.Table["delete"] objet alors il contient une valeur de chaîne « Supprimer ». Articles de propriété [2] pointant ici pour LCID 1033. Cela signifie que gestionnaire de ressources contient déjà chaîne localisée pour la clé de ressource Supprimer dans la langue 1033 . Est-ce que quelqu'un sait où peut être l'erreur?

Était-ce utile?

La solution

Je pense aussi que vous devez déclarer et utiliser votre propre dictionnaire pour le stockage depuis ResourceSets est marqué comme obsolète dans .NET 4.0

Autres conseils

Je me suis retrouvé répondre. Voici les détails: Nous avons la mise en œuvre personnalisée de ResourceManager comme ceci:

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));
    }
}

Dans .NET 2.0, il fonctionne bien, mais dans .NET 4.0 quelque chose a changé dans la mise en œuvre de ResourceManager.I pense que problème est dans le constructeur parameterless qui dans .NET 2.0 domaine privé instancier this._resourceSets (qui est utilisé plus tard dans InternalGetResourceSet pour Monitor.Enter). Mais dans le constructeur de .NET 4.0 ne parameterless instancier champ privé this._resourceSets et donc il ne parvient plus tard (comme décrit Abobe).

Je dois réécrire mon gestionnaire de ressources personnalisé que cela fonctionne sur:

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;
    }
  }
}

« Magic » est ici que je dois remplacer la méthode InternalGetResourceSet pour charger mes ressources de stockage sur mesure (db) et à l'arrière de retour « ResourceSet » pour la culture spécifiée. Maintenant, il fonctionne comme un charme.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top