2012-02-27 34 views
6

Wiem, że istnieje sporo statycznych narzędzi do analizy dla C# lub .Net wokół. Zobacz tę question dla dobrej listy dostępnych narzędzi. Używałem niektórych z nich w przeszłości i mają dobry sposób na wykrywanie problemów.Narzędzie do analizy statycznej do sprawdzania blokowania przed dostępem do zmiennej

Obecnie poszukuję sposobu automatycznego egzekwowania niektórych zasad blokowania, które mamy w naszych zespołach. Na przykład chciałbym wymusić następujące zasady:

„Każda metoda publiczny, który używa członek foo musi uzyskać blokadę na pasku” Albo „Każde wywołanie foobar przypadku musi być na zewnątrz zamka do bar "

Pisanie niestandardowych reguł FxCop, jeśli jest to feasible, wydaje się dość złożone. Czy jest jakiś prostszy sposób na zrobienie tego?

Odpowiedz

0

Jednym z możliwych rozwiązań może być implementacja Code Contracts. Użytkownik definiuje reguły, uruchamia je pod czasu kompilacji (można go również zintegrować ze środowiskiem CI, jeśli istnieje) i uzyskać wyniki.

Na pl przykład użycia CodeContracts jak narzędzie dla kodu statycznych Analys patrz:

Static Code Analysis and Code Contracts

+1

Jak napisać umowę, która zabrania dostępu do niektórych danych, chyba że zostanie zrobiony zamek? – svick

+0

@svick: blokowanie nie jest konieczne oznacza, że ​​używasz instrukcji 'lock'. Możesz użyć innego typu obiektów 'sync', aby móc sprawdzić, czy obiekt jest sygnalizowany/zablokowany/... cokolwiek. – Tigran

+0

OK, ale nadal, jak napisać umowę kodu, która sprawdza każdy dostęp do pola? – svick

1

Wielowątkowość jest trudne. Używanie zamków nie jest jedynym sposobem na bezpieczne działanie wątków. Programista może korzystać z nieblokującej synchronizacji z pętlą i Interlocked.CompareExchange lub z innego mechanizmu. Reguła nie może określić, czy coś jest bezpieczne dla wątków.

Jeśli celem reguł jest zapewnienie wysokiej jakości kodu, myślę, że najlepszym sposobem, aby to osiągnąć, jest stworzenie wersji bezpiecznej dla wątków klasy, która jest prosta do konsumpcji. Wprowadza kontrole, że bardziej złożony kod synchronizacji jest modyfikowany tylko przez recenzentów kodu, którzy rozumieją wielowątkowość.

+0

"Wprowadzić kontrole, że bardziej złożony kod synchronizacji jest modyfikowany tylko przez recenzentów kodu, którzy rozumieją wielowątkowość": Właściwie to właśnie staramy się zautomatyzować, ponieważ obecnie nie mamy procesu/przepływu/siły roboczej zatwierdzić każdą modyfikację. Nie próbujemy egzekwować poprawności, tylko upewniając się, że oczywiste błędy się nie prześlizgną. –

1

Z NDepend można napisać code rule over a LINQ query (CQLinq) który mógłby wyglądać następująco:

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 } 

Zasadniczo będzie tenis metody, które używa pola foo, bez użycia dziedzinie poprzeczkę lub bez poddawania Monitor Enter lub Exit . Nie jest to dokładnie to, o co prosisz, ponieważ chcesz zablokować blokadę na pasku, ale jest to proste i dość bliskie.

zauważa, że ​​można też pisać ...

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

... ograniczyć użycie konkretnego zapisu/pole przypisać na foo.

+0

Więc NDepend ponownie działa wygenerowany IL, a nie odpowiadający kod C#? Stąd walidacja w stosunku do klasy Monitor. –

+0

Rzeczywiście, Vincent, podczas gdy NDepend analizuje również C# dla komentarza i C# dane Cyclomatic Complexity: http://www.ndepend.com/Doc_CI_Inputs.aspx –

Powiązane problemy