2012-02-27 55 views
6

我知道有很多針對C#或.Net的靜態分析工具。請參閱此question以獲取可用工具的完整列表。我過去曾使用過其中的一些,他們有很好的檢測問題的方法。靜態分析工具在訪問變量之前檢查鎖定

我目前正在尋找一種方法來自動執行我們團隊中的一些鎖定規則。比如我想遵守以下規則:

或者 「使用會員必須酒吧獲得鎖的每一個公共方法」「到foobar的事件每次調用必須是外鎖bar

編寫自定義FxCop規則(如feasible)似乎相當複雜。有沒有更簡單的方法呢?

回答

0

可能的解決方案之一可能是實施Code Contracts。你定義規則,在編譯時間(如果有的話,也可以集成到你的CI環境中)運行它們並獲得結果。

對於連接例如使用CodeContracts像靜態代碼analys工具的看到:

Static Code Analysis and Code Contracts

+1

您會如何撰寫合同禁止訪問某個字段,除非鎖定? – svick 2012-02-27 17:04:04

+0

@svick:鎖定並不一定意味着你使用'lock'語句。您可以使用其他類型的「同步」對象,以便能夠檢查對象是否被信號/鎖定/ ......無論如何。 – Tigran 2012-02-27 18:58:08

+0

好的,但仍然,你如何編寫一個代碼合同來檢查對該領域的每一次訪問? – svick 2012-02-27 19:03:05

1

多線程是困難的。使用鎖定不是使操作線程安全的唯一方法。開發人員可以使用非阻塞同步的循環和Interlocked.CompareExchange或其他一些機制。規則無法確定某些內容是否是線程安全的。

如果規則的目的是爲了確保高質量的代碼,我認爲最好的方法是創建一個易於使用的類的線程安全版本。進行檢查,更復雜的同步代碼只能在理解多線程的開發人員的代碼審查下修改。

+0

「將檢查置於更復雜的同步代碼僅在開發人員瞭解多線程的代碼審查下修改」:實際上,這正是我們試圖自動化的,因爲我們目前沒有流程/流程/人力驗證每個修改。我們不是試圖強化正確性,只是確保明顯的錯誤不會漏掉。 – 2012-02-28 15:19:31

1

隨着NDepend你可以寫一個code rule over a LINQ query (CQLinq)可能看起來像:

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 } 

基本上就會使用領域,不使用現場酒吧匹配方法,或不調用Monitor EnterExit 。這不完全是你要求的,因爲你想明確地鎖定欄,但這很簡單,非常接近。

注意,你也可以寫...

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

...來限制特定的寫/指派字段使用。

+0

因此,NDepend再次生成IL,而不是相應的C#代碼?因此對Monitor類進行驗證。 – 2012-02-28 15:16:13

+0

確實是文森特,而NDepend也解析了C#的評論和C#循環複雜度指標:http://www.ndepend.com/Doc_CI_Inputs.aspx – 2012-02-29 15:44:58