【问题标题】:Static analysis tool to check locking before access to variable在访问变量之前检查锁定的静态分析工具
【发布时间】:2012-02-27 16:34:56
【问题描述】:

我知道周围有很多用于 C# 或 .Net 的静态分析工具。请参阅此question 以获取可用工具的良好列表。我过去使用过其中的一些,它们有很好的检测问题的方法。

我目前正在寻找一种方法来自动执行我们团队中的一些锁定规则。例如,我想执行以下规则:

“每个使用成员 foo 的公共方法都必须在 bar 上获得一个锁” 或者 "每次调用 foobar 事件都必须在 bar 的外部锁定"

编写自定义 FxCop 规则,如果 feasible,似乎相当复杂。有没有更简单的方法呢?

【问题讨论】:

    标签: c# .net multithreading static-analysis


    【解决方案1】:

    多线程很难。使用锁并不是使操作线程安全的唯一方法。开发人员可以使用循环的非阻塞同步和 Interlocked.CompareExchange 或其他一些机制。规则无法确定某事是否是线程安全的。

    如果规则的目的是确保高质量的代码,我认为最好的方法是为你的类创建一个易于使用的线程安全版本。检查更复杂的同步代码只有在了解多线程的开发人员的代码审查下才能修改。

    【讨论】:

    • "检查更复杂的同步代码只有在了解多线程的开发人员的代码审查下才能修改":实际上,这正是我们试图自动化的,因为我们目前不拥有流程/流程/人力来验证每个修改。我们不会试图强制执行正确性,只是确保不会漏掉明显的错误。
    【解决方案2】:

    使用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 }
    

    基本上它将匹配使用字段 foo、不使用字段 bar 或不调用 Monitor EnterExit 的方法。这并不完全是您所要求的,因为您想明确地锁定 bar,但这很简单而且非常接近。

    注意你也可以写...

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

    ... 限制 foo 上的特定写入/分配字段使用。

    【讨论】:

    • 所以 NDepend 再次使用生成的 IL,而不是相应的 C# 代码?因此针对 Monitor 类进行验证。
    • 确实是 Vincent,而 NDepend 也解析 C# 以获取注释和 C# 循环复杂度指标:ndepend.com/Doc_CI_Inputs.aspx
    【解决方案3】:

    一种可能的解决方案是实现Code Contracts。您定义规则,在编译时运行它们(如果有的话,也可以集成到您的 CI 环境中)并获得结果。

    有关将 CodeContracts 用作代码静态分析工具的示例,请参阅:

    Static Code Analysis and Code Contracts

    【讨论】:

    • 你会如何编写一个禁止访问某个文件的合同,除非被锁定?
    • @svick:锁定并不意味着您使用lock 语句。您可以使用其他类型的 sync 对象,以便能够检查对象是否已发出信号/锁定/...无论如何。
    • 好的,但是,您如何编写代码合约来检查对该字段的每次访问?
    • @svick:例如,您可以: 1. 定义属性而不是字段 2. 您可以在编译时注入 IL,在每个 __get 字段访问时触发一个事件并检查您的规则。
    猜你喜欢
    • 2011-04-11
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2021-11-10
    • 2013-11-20
    • 1970-01-01
    相关资源
    最近更新 更多