Cas*_*ite 3 c# resharper idisposable using-statement
我正在使用“使用语句”来确保正确清理 StreamWriter。
using (StreamWriter fout = new StreamWriter(tempFile))
{
data.ForEach(line => fout?.WriteLine(line));
}
Run Code Online (Sandbox Code Playgroud)
我收到 ReSharper 警告“访问已处理的关闭”,据我所知,这是因为变量fout
可能已关闭。我知道在某些用途中可能会发生,但在这种情况下,是否有可能fout
在调用时已经被处理WriteLine
?
欢迎使用堆栈溢出。
ReSharper 的Access to disposed closure
警告应该只在 LINQ 延迟执行捕获对可能在执行发生之前处理的闭包的引用时发生。
这里是否是这种情况取决于ForEach
您调用的方法。如果您正在调用,List.ForEach
那么您不会构成延迟执行链,因此fout
显然对每次调用都有效。当涉及到这种方法时,ReSharper 当然应该更了解。
但是还有其他ForEach
方法,包括自定义方法,ReSharper 可能不知道或实际上可能会延迟。如果它们写得很好,那么它们将阻塞直到它们完成,但我已经看到自定义ForEach
扩展方法没有。由于 ReSharper 无法确定,除非代码InstantHandle
通过 action 参数上的注释告诉它,因此它会警告您。
如果你在List.ForEach
这里工作,那么我建议你放弃它,转而使用一个很好的旧foreach
语句。对于其他扩展,请查明它是否会阻塞或是否有可能在任何情况下推迟执行。 Observable.ForEach
并且Parallel.ForEach
两者似乎都会阻止执行,直到集合被完全处理或事件源关闭。其他代码可能不会这样做,事后追踪这样的错误可能会很痛苦。如果可以,请检查方法的来源,如果无法访问来源,请联系库开发人员。
一旦您确定这ForEach
肯定会阻塞并且永远不会推迟执行,那么您可以继续并抑制警告:
// ReSharper disable AccessToDisposedClosure
data.ForEach(line => fout?.WriteLine(line));
// ReSharper restore AccessToDisposedClosure
Run Code Online (Sandbox Code Playgroud)