2012-02-27 7 views
6

So che ci sono un paio di strumenti di analisi statici per C# o .Net intorno. Vedere questo question per un buon elenco di strumenti disponibili. Ho usato alcuni di quelli in passato e hanno un buon modo di rilevare i problemi.Strumento di analisi statica per controllare il blocco prima dell'accesso alla variabile

Attualmente sto cercando un modo per applicare automaticamente alcune regole di blocco che abbiamo nei nostri team. Per esempio vorrei far rispettare le seguenti regole:

"Ogni metodo pubblico che utilizza membro foo deve acquisire un blocco su bar" O "Ogni chiamata a foobar evento deve essere serratura esterna per bar "

Scrivere regole personalizzate FxCop, se feasible, sembra piuttosto complesso. C'è un modo più semplice per farlo?

risposta

0

Una delle possibili soluzioni potrebbe essere l'implementazione di Code Contracts. Si definiscono le regole, le si esegue al tempo di compilazione (quindi può anche essere integrato nel proprio ambiente CI se presente) e ottenere risultati.

Ad it esempio di utilizzo di CodeContracts come uno strumento per analys statici di codice vedere:

Static Code Analysis and Code Contracts

+1

Come scriveresti un contratto che vieta l'accesso a un determinato archivio a meno che non venga presa una serratura? – svick

+0

@svick: il blocco non è necessario per utilizzare l'istruzione 'lock'. Puoi usare altri oggetti 'sync' per poter controllare se l'oggetto è segnalato/bloccato/... qualsiasi cosa. – Tigran

+0

OK, ma come si scrive un contratto di codice che controlla ogni accesso al campo? – svick

1

Multithreading è difficile. L'utilizzo di lock non è l'unico modo per rendere le operazioni thread-safe. Uno sviluppatore può utilizzare la sincronizzazione non bloccante con un loop e Interlocked.CompareExchange o qualche altro meccanismo. Una regola non può determinare se qualcosa è sicuro per i thread.

Se lo scopo delle regole è quello di garantire un codice di alta qualità, penso che il modo migliore per farlo sia quello di creare una versione thread-safe della classe che sia semplice da utilizzare. Metti in atto controlli che il codice di sincronizzazione più complesso viene modificato solo in fase di revisione del codice da parte degli sviluppatori che comprendono il multithreading.

+0

"Verificare che il codice di sincronizzazione più complesso venga modificato solo in seguito alla revisione del codice da parte degli sviluppatori che comprendono il multithreading": in realtà, è esattamente ciò che stiamo tentando di automatizzare, perché al momento non abbiamo il processo/flusso/manodopera per convalidare ogni modifica. Non stiamo cercando di far rispettare la correttezza, ma assicurandoci che errori ovvi non sfuggano. –

1

Con NDepend si potrebbe scrivere un code rule over a LINQ query (CQLinq) che potrebbe apparire come:

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 } 

Fondamentalmente lo farà partite metodi che utilizza il campo foo, senza utilizzare il campo bar, o senza chiamare Monitor Enter o Exit . Questo non è esattamente quello che stai chiedendo, dal momento che vuoi bloccare esplicitamente sulla barra, ma questo è semplice e abbastanza vicino.

rileva che si può anche scrivere ...

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

... per limitare una specifica utilizzo di scrittura/campo di assegnazione sulla foo.

+0

Quindi NDepend lavora di nuovo l'IL generato e non il codice C# corrispondente? Da qui la convalida della classe Monitor. –

+0

Vincent, mentre NDepend analizza anche C# per i commenti e le metriche di complessità ciclomatica C#: http://www.ndepend.com/Doc_CI_Inputs.aspx –