【问题标题】:Does this Resharper fix for disposed closure warning make any sense?这个 Resharper 对已处置关闭警告的修复是否有意义?
【发布时间】:2013-01-08 15:53:59
【问题描述】:

我正在努力消除静态代码分析中的一些警告。 在一个特定情况下,没有对 ManualResetEvent 进行处理。

有问题的代码在主线程上执行Func 并阻塞调用线程一定的毫秒数。我意识到这听起来很奇怪,但它超出了这个问题的范围,所以请耐心等待。

假设我像这样添加using 语句:

object result = null;
using (var completedEvent = new ManualResetEvent(false))
{
    _dispatcher.BeginInvoke((Action)(() =>
        {
            result = someFunc;
            completedEvent.Set();  // Here be dragons!
        }));

    completedEvent.WaitOne(timeoutMilliseconds);
    return result;
}

现在,我意识到这可能会导致问题。我也碰巧使用了 Resharper,它警告我“访问已处置的闭包”消息。

Resharper 建议通过将违规行更改为:

if (completedEvent != null)
{ 
    completedEvent.Set();
}

现在,建议的解决方案让我感到困惑。在正常情况下,没有理由通过using 语句将变量设置为null.NET 中的闭包是否有一些实现细节可以保证在已关闭的变量被释放后变量为null

作为一个额外的问题,处理ManualResetEvent 的问题有什么好的解决方案?

【问题讨论】:

  • @Steven 为什么代理必须使用completedEvent 的副本?你能解释一下这一点吗?

标签: c# .net closures resharper


【解决方案1】:

您混淆了 ReSharper 的“快速修复”和“上下文操作”。当 ReSharper 提出修复某些问题时,您很可能会在那里看到一个灯泡。您在这里看不到灯泡,因为没有快速修复此警告的方法。

但除了快速修复之外,ReSharper 还具有“上下文操作”,它可以为您执行一些常规任务(将它们视为小型重构)。当 ReSharper 对光标下的代码有上下文操作时,它会显示一个选择。在这里,您会看到一个名为“Check if something is not null”的上下文操作。它与警告无关,并且没有约定在处理变量后将设置为 null。

此外,当您按 Alt-Enter 时,您会看到一个被删除的灯泡,这让您觉得 ReSharper 没有建议对此警告进行任何快速修复,但它可以使用 cmets 禁用它。事实上,这是让这个警告轻松消失的唯一方法。但我会改写这段代码。

【讨论】:

    【解决方案2】:

    我在几个小时前就遇到了这个问题。

    这是一场虚惊。 R# 不理解在设置事件之前执行会阻塞,即使这会将处理推迟到正确的时刻。

    IMO 这是一个很好的解决方案。忽略 R#。

    建议在调用completedEvent.Set() 时捕获ObjectDisposedException,以防超时已过期且事件已被处理。我认为这不会阻止 R# 警告,但它是安全的。

    【讨论】:

    • "执行将阻塞,直到设置事件"执行不会阻塞,它会在超时后运行。
    • 哎呀。是的。错过了超时。我被我自己的代码的相似性所吸引,以至于我错过了。
    • 正如@Hamlet 提到的,Set() 方法可能在处理后被调用,以防超时。我在一段非常相似的代码中捕获了ObjectDisposedException。这是我当时能想到的最安全的解决方案,尽管我更喜欢没有例外的解决方案。
    【解决方案3】:

    我认为,你必须检查 null,而且你必须捕获这个异常。 想象一下如果someFunc 运行的次数超过timeoutMilliseconds 会发生什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多