6

我正在努力摆脱静态代码分析中的一些警告。在一个特定情况下,没有对ManualResetEvent.

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

假设我添加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();
}

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

作为一个额外的问题,什么是处理问题的好方法ManualResetEvent

4

3 回答 3

6

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

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

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

于 2013-01-09T06:29:37.510 回答
2

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

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

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

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

于 2013-01-08T15:55:23.247 回答
1

我认为,您必须检查 null,而且您必须捕获此异常。想象一下如果someFunc运行超过timeoutMilliseconds.

于 2013-01-08T16:06:55.523 回答