2011-04-18 7 views
6

que tienen Singleton objeto 'Servicio' y dos métodos para inicializar y liberarlo:¿Por qué la expresión es siempre cierta para 'double-checked-locking'?

public class BaseService 
{ 
    protected static readonly object StaticLockObject = new object(); 
} 

public abstract class WebServiceBase<TService> : BaseService 
    where TService : System.Web.Services.Protocols.SoapHttpClientProtocol, new() 
{ 
    protected static void EnsureServiceIsOpened() 
    { 
     if (Service == null) 
     { 
      lock (StaticLockObject) 
      { 
       if (Service == null) 
       { 
        Service = new TService(); 
       } 
      } 
     } 
    } 

    protected static void EnsureServiceIsClosed() 
    { 
     if (Service != null) 
     { 
      lock (StaticLockObject) 
      { 
       if (Service != null) // Why expression is always true 
       { 
        Service.Dispose(); 
        Service = null; 
       } 
      } 
     } 
    } 

Para la línea con comentario ReSharper (yo uso la versión 5.1) muestra una advertencia mencionada ...

pregunta 1: ¿Por qué?

Pregunta 2: ¿Por qué no muestra el mensaje "similar" en el método "EnsureServiceIsOpened"?

Gracias.

Respuesta

2

Es un error en el motor de análisis de código ReSharper 5.X. Solucionado en ReSharper 6.0.

Por cierto, ReSharper 6 trae más cosas análisis de doble patrón de bloqueo :)

4

Resharper hace un análisis limitado del código y ve las dos declaraciones if anidadas que comprueban exactamente lo mismo. En un entorno de subproceso único, el comentario por reafilamiento es perfectamente cierto: no hay forma de que Service sea null después del primer if. En un entorno multiproceso, por supuesto, esto no se aplica, ya que Service podría cambiarse desde el exterior. Este es un caso en el que debe anotar el código para resharper o suprimir el mensaje para este archivo, ya que no es cierto en un entorno multiproceso.

+0

Es no rompa su código de una sola aplicación roscado - por qué esto una advertencia * * me intriga. :/ – mayu

+0

Porque podría suceder. El análisis de código solo puede ir tan lejos, y es por eso que aparece esta advertencia. – Femaref

+0

No tengo ningún problema con que esto se muestre por Resharper, no creo que deba ser una advertencia. :) – mayu

3

Parece que Resharper está cometiendo un error en este análisis. Como Service no es una variable local, no puede saber que esa expresión siempre será verdadera.

La razón por la cual el error no aparece para la primera versión es probable porque el idioma de doble verificación es tan común, y esa es su forma habitual. Probablemente probaron para ese caso y eliminaron la advertencia errónea.

La técnica que se muestra en EnsureServiceIsClosed no es común porque contiene una condición de carrera. Otro subproceso podría estar utilizando el objeto indicado por Service mientras o después de que se elimine. Esto no sería posible si el código que utiliza el Servicio se bloquea en StaticLockObject, pero si lo hace, entonces no hay razón para hacer todo este doble rigamarole de bloqueo para crear y eliminar el objeto. Por lo tanto, es virutalmente cierto que este código es defectuoso.

Cuestiones relacionadas