Pregunta

Mi código:

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

En el proyecto actual compilado bajo .NET 2.0 funciona todo como exceptuado. Variable str contiene cadena de recursos para LCID 1033 -. Eliminar , esto está bien

Ahora estamos actualizando a .NET 4.0, proyecto recompilado por debajo del objetivo NET Framework 4.0. Ahora compilado como .NET 4.0 asambleas, se lanza una excepción System.ArgumentNullException con el mensaje Valor no puede ser nulo .STACK de seguimiento:.

   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)

interesante aquí es StackTrace, donde apunta al método de marco interno en ResourceManager.InternalGetResourceSet lo que provoca a la llamada Monitor.Enter con objeto nulo. Pero yo llamo el método GetString con parámetros no nulos GetString ( "Borrar", nueva CultureInfo (1033)) .

Este error parece ser similar a la en System.Threading. Monitor.Enter. Tal vez algún error en Monitor.Enter, o algo más?

Actualización: Cuando miro en depurador en resourceManager.ResourceSets.Items[2].Value.Table["delete"] objeto entonces contiene valor de cadena "Borrar". Los productos de propiedad [2] aquí apuntando a LCID 1033. Esto significa que ya contiene administrador de recursos para la cadena localizada clave de recurso eliminar en el lenguaje 1033 . ¿Alguien sabe dónde puede estar el error?

¿Fue útil?

Solución

También creo que se debe declarar y utilizar su propio diccionario para el almacenamiento ya ResourceSets se marcan como obsoletos bajo .NET 4.0

Otros consejos

Me pareció responder a mí mismo. Aquí están los detalles: Tenemos implementación personalizada de ResourceManager como esto:

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

En .NET 2.0 que funciona bien, pero en .NET 4.0 algo ha cambiado en la aplicación de ResourceManager.I pensar que es un problema en el constructor sin parámetros, que en .NET 2.0 ámbito privado instantiate this._resourceSets (que se utiliza más adelante en InternalGetResourceSet para Monitor.Enter). Pero en .NET 4.0 constructor sin parámetros no se instancian ámbito privado this._resourceSets y por lo tanto se produce un error después (como se describe Abobe).

Me debe reescribir mi administrador de recursos a medida que esto funcione:

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" aquí es que tengo que sobreescribir el método InternalGetResourceSet para cargar mis recursos de almacenamiento personalizada (db) y de nuevo de retorno "ResourceSet" para la cultura especificada. Ahora funciona como un encanto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top