2012-02-27 9 views
6

Sé que hay unas cuantas herramientas de análisis estático para C# o .Net. Consulte esto question para obtener una buena lista de herramientas disponibles. He utilizado algunos de esos en el pasado y tienen una buena forma de detectar problemas.Herramienta de análisis estático para comprobar el bloqueo antes de acceder a la variable

Actualmente estoy buscando una forma de aplicar automáticamente algunas reglas de bloqueo que tenemos en nuestros equipos. Por ejemplo, me gustaría hacer cumplir las reglas siguientes:

"Cada método público que utiliza miembro de foo debe adquirir un bloqueo en barra" O "Cada llamada a foobar evento debe ser bloqueo exterior para bar "

Escribir reglas personalizadas de FxCop, si es feasible, parece bastante complejo. ¿Hay alguna forma más simple de hacerlo?

Respuesta

0

Una de las posibles soluciones podría ser la implementación de Code Contracts. Defina reglas, ejecútelas al tiempo de compilación (de modo que también puede integrarse en su entorno de CI, si existe) y obtenga resultados.

para EN ejemplo del uso de CodeContracts como una herramienta para analys estático de código ver:

Static Code Analysis and Code Contracts

+1

¿Cómo redactaría un contrato que prohíbe el acceso a un determinado archivo a menos que se realice un bloqueo? – svick

+0

@svick: bloqueo no necesariamente significa que utiliza la instrucción 'lock'. Puede usar otros objetos tipo 'sync' para poder verificar si el objeto está señalizado/bloqueado/... lo que sea. – Tigran

+0

OK, pero igual, ¿cómo se escribe un contrato de código que verifique cada acceso al campo? – svick

1

multihilo es difícil. Usar bloqueos no es la única forma de hacer que las operaciones sean seguras para hilos. Un desarrollador puede usar sincronización sin bloqueo con un bucle e Interlocked.CompareExchange, o algún otro mecanismo en su lugar. Una regla no puede determinar si algo es seguro para subprocesos.

Si el propósito de las reglas es garantizar un código de alta calidad, creo que la mejor manera de hacerlo es crear una versión segura para subprocesos de su clase que sea fácil de consumir. Ponga controles en lugar de que el código de sincronización más complejo solo se modifique bajo la revisión del código por parte de los desarrolladores que entienden el multihilo.

+0

"Ponga controles en lugar de que el código de sincronización más complejo solo se modifique bajo revisión de código por los desarrolladores que entienden el multihilo": en realidad, eso es exactamente lo que estamos tratando de automatizar, porque actualmente no tenemos el proceso/flujo/mano de obra para validar cada modificación. No estamos tratando de imponer la corrección, simplemente asegurándonos de que los errores obvios no se resuelvan. –

1

Con NDepend se podría escribir un code rule over a LINQ query (CQLinq) que podría parecerse a:

warnif count > 0 from m in Methods where 
m.IsUsing ("YourNamespace.YourClass.foo") && ( 
    ! m.IsUsing ("YourNamespace.YourClass.bar") || 
    ! m.IsUsing ("System.Threading.Monitor.Enter(Object)".AllowNoMatch()) || 
    ! m.IsUsing ("System.Threading.Monitor.Exit(Object)".AllowNoMatch())) 
select new { m, m.NbLinesOfCode } 

Básicamente se va a los partidos métodos que utiliza el campo foo, sin necesidad de utilizar el campo barra de, o sin llamar Monitor Enter o Exit . Esto no es exactamente lo que está pidiendo, ya que desea bloquear explícitamente en la barra, pero esto es simple y bastante cercano.

Toma nota de que también se puede escribir ...

m.AssignField("YourNamespace.YourClass.foo") 

... para restringir el uso de una escritura/campo de asignación específica sobre foo.

+0

¿Entonces NDepend vuelve a funcionar la IL generada, y no el código C# correspondiente? De ahí la validación en contra de la clase Monitor. –

+0

Indeed Vincent, mientras que NDepen analiza también C# para comentarios y C# Cyclomatic Complexity metrics: http://www.ndepend.com/Doc_CI_Inputs.aspx –

Cuestiones relacionadas