我正在使用“使用声明”来确保StreamWriter被正确清理。
using (StreamWriter fout = new StreamWriter(tempFile))
{
data.ForEach(line => fout?.WriteLine(line));
}
我收到ReSharper警告“访问已关闭的封闭”,据我了解,这是因为变量fout
可能已封闭。我知道在某些情况下可能会发生这种情况,但是在这种情况下,调用fout
时是否可能已经WriteLine
被处置了?
答案 0 :(得分:2)
欢迎堆栈溢出。
ReSharper的Access to disposed closure
警告仅在LINQ延迟执行捕获到对可能在执行发生之前处置的闭包的引用时才发生。
在这种情况下,是否取决于所调用的ForEach
方法。如果您要调用List.ForEach
,那么您就不会构成延迟的执行链,因此fout
显然对每次调用都有效。 ReSharper在使用这种方法时肯定应该更加了解。
但是还有其他ForEach
方法,包括自定义方法,ReSharper可能不知道这些方法,或者实际上可能会延迟。如果编写得当,则它们将阻塞直到完成,但是我见过自定义的ForEach
扩展方法。由于ReSharper不能确定,除非代码在action参数上使用InstantHandle
注释告诉它,所以它会警告您。
如果您在这里使用List.ForEach
,那么我建议您放弃它,而使用一个好的旧foreach
语句。对于其他扩展,请确定其是否阻塞,或者是否有可能在任何情况下推迟执行。 Observable.ForEach
和Parallel.ForEach
似乎都阻止执行,直到完全处理了集合或事件源关闭为止。其他代码可能不会这样做,而事后寻找这样的错误可能会很痛苦。如果可以,请检查该方法的源,如果无法访问该源,请与库开发人员联系。
一旦您确定此ForEach
肯定会阻塞并且从不延误执行,则可以继续操作并取消警告:
// ReSharper disable AccessToDisposedClosure
data.ForEach(line => fout?.WriteLine(line));
// ReSharper restore AccessToDisposedClosure