Добро пожаловать в переполнение стека.
Предупреждение Access to disposed closure
от ReSharper должно появляться только тогда, когда LINQ с задержкой выполнения захватывает ссылку на замыкание, которое может быть удалено до выполнения.
В данном случае это зависит от того, какой метод ForEach
вы вызываете.Если вы вызываете List.ForEach
, значит, вы не составляете цепочку отложенного выполнения, поэтому fout
, очевидно, будет действительным для каждого вызова.ReSharper, безусловно, должен знать лучше, когда речь заходит об этом методе.
Но есть и другие ForEach
методы, в том числе и пользовательские, о которых ReSharper может не знать или которые на самом деле могут быть отложены.Если они хорошо написаны, они будут блокироваться до завершения, но я видел пользовательские методы расширения ForEach
, которые этого не делают.Так как ReSharper не может знать наверняка, пока код не сообщит ему аннотацию InstantHandle
к параметру действия, он предупредит вас.
Если вы работаете с List.ForEach
здесьтогда я бы посоветовал вам отказаться от старого доброго заявления foreach
.Что касается других расширений, выясните, блокирует ли оно или есть ли вероятность, что оно будет откладывать выполнение при любых обстоятельствах.Observable.ForEach
и Parallel.ForEach
оба, кажется, блокируют выполнение, пока коллекция не будет полностью обработана или источник событий не закроется.Другой код может этого не делать, и отслеживание ошибок может быть проблемой после этого.Проверьте источник для метода, если можете, или обратитесь к разработчику библиотеки, если вы не можете получить доступ к источнику.
Как только вы установили, что этот ForEach
определенно заблокируется иникогда не откладывает выполнение, тогда вы можете пойти дальше и подавить предупреждение:
// ReSharper disable AccessToDisposedClosure
data.ForEach(line => fout?.WriteLine(line));
// ReSharper restore AccessToDisposedClosure