这个Resharper修复处理关闭警告是否有意义?
我正在努力摆脱静态代码分析中的一些警告。 在一个特定情况下,没有在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
问题的解决方案是什么?
你正在混淆ReSharper的“快速修复”和“上下文动作”。 当ReSharper建议修理某些东西时,很可能你会在那里看到一个灯泡。 你没有在这里看到一个灯泡,因为这个警告没有快速修复。
但除了快速修复之外,ReSharper还具有“上下文操作”,它可以为您执行一些例行任务(将它们视为小型重构)。 当ReSharper对光标下的代码有上下文操作时,它会显示一个选择。 在这里,您可以看到一个名为“检查某些内容是否为空”的上下文操作。 它与警告没有关系,并且没有约定在处理变量之后将其设置为null。
此外,当您按Alt-Enter时,您会看到一个标记出来的灯泡,让您觉得ReSharper不建议对此警告进行任何快速修复,但可以通过注释禁用它。 事实上,这是使这个警告轻易消失的唯一方法。 但我改写了这段代码。
几个小时前我才遇到这个问题。
这是一个误报。 R#不理解执行将在事件设置之前阻塞,即使这会将处理推迟到恰当的时刻。
IMO这是一个很好的解决方案。 只需忽略R#。
建议在调用completedEvent.Set()
时捕获ObjectDisposedException
,以防超时过期且事件已被ObjectDisposedException
。 我不认为这会阻止R#警告,但它是安全的。
我想,你必须检查null,而且你必须捕获这个exception。 想象一下,如果someFunc
运行超过timeoutMilliseconds
会发生什么。