2008-10-20 15 views
6

Recientemente tuve un error que solo se manifestó cuando la biblioteca se creó como una versión de lanzamiento en lugar de una versión de depuración. La biblioteca es .NET dll con un contenedor COM y estoy usando CoCreateInstance para crear una clase desde el dll en una aplicación C++ no administrada. Cuando finalmente rastreé el error fue causado por el acceso a un objeto singleton. Tenía la instancia singleton declarada como tal:¿Cuál es la diferencia en estas formas de crear la instancia estática para un singleton?

private static readonly MyObjectType s_instance = new MyObjectType; 

luego se puede acceder con:

public static MyObjectType Instance 
    { 
     get 
     {        
      return s_instance; 
     } 
    } 

este estaba fallando. Cambiándolo a:

private static MyObjectType s_instance; 

public static MyObjectType Instance 
    { 
     get 
     {    
      if (s_instance==null) 
      { 
       s_instance = new MyObjectType(); 
      } 
      return s_instance; 
     } 
    } 

solucionó el problema. ¿Alguna idea de por qué el uso inicial no funcionó y si hay inconvenientes para hacerlo de cualquier manera?

El dll de lanzamiento parecía ser perfectamente utilizable desde otra aplicación administrada.

+0

¿Cómo se manifestó este error? ¿Se bloqueó? ¿Hubo un mensaje de error? –

+0

La llamada a CoCreateInstance acaba de devolver 'ClassNotRegistered' cada vez. Pero solo en una construcción relaese. en una versión de depuración todo funcionó bien. –

+0

Su solución no es segura para subprocesos. – Joe

Respuesta

8

Intente agregar un constructor estático (vacío) o inicialice el singleton en un constructor estático.

Jon Skeet tiene una discusión completa de los patrones singleton here. No estoy seguro de por qué falló, pero supongo que podría estar relacionado con la bandera "beforefieldinit". Vea su 4to ejemplo, donde agrega un constructor estático para ajustar esta bandera. No pretendo ser un experto en beforefieldinit, pero este síntoma parece ajustarse a algunos de los síntomas discutidos en here.

+0

Ni siquiera sabía que existían los constructores estáticos. ¡Gracias (sin saberlo) por educarme! – Rik

+0

Bingo. Agregar un constructor estático vacío solucionó el problema. Gracias. 2 días de mi vida, nunca volveré. –

0

Simplemente reiterando lo que dijo Marc Gravell, pero suena mucho como un problema de campo anterior, lo que significa que el constructor estático vacío es su solución. Tendría que publicar cualquiera y todos los constructores en la clase para obtener una respuesta definitiva.

El segundo método tiene la ventaja de la carga diferida (cuando eso es una ventaja).

+0

de hecho, como dije antes, la solución fue agregar un constructor estático. –

Cuestiones relacionadas