Доступ к предупреждению о удаленном закрытии в операторе using

Я использую «оператор использования», чтобы убедиться, что StreamWriter очищается должным образом.

using (StreamWriter fout = new StreamWriter(tempFile))
{
    data.ForEach(line => fout?.WriteLine(line));
}

Я получаю предупреждение ReSharper «Доступ к удаленному закрытию», которое, насколько я понимаю, связано с тем, что переменная fout может быть закрыта. Я понимаю, что в некоторых случаях это могло произойти, но в этом случае возможно ли удаление fout при вызове WriteLine?


person Casey White    schedule 25.01.2019    source источник
comment
Точный ответ заключается в том, что это полностью зависит от того, что метод ForEach делает внутри с данным делегатом. И я, и вы знаете, что этого не произойдет, но компилятор не может быть уверен, отсюда и предупреждение.   -  person Alejandro    schedule 25.01.2019
comment
Пока вы закрываете поток после использования, у вас не должно возникнуть проблем с его кодированием без оператора using. Но да, если вы не закроете его, это может вызвать много уровней боли.   -  person nalnpir    schedule 25.01.2019
comment
Похоже, это предупреждение Resharper, а не предупреждение компилятора (о чем вы могли упомянуть). Я считаю, что он говорит о том, что лямбда-делегат, который передает ForEach, имеет закрытие, которое включает переменную, которая будет удалена с помощью метода Using. Если ForEach кэширует делегата, он получит доступ к fout после того, как он, возможно, был удален. Прочтите полностью resharper-support.jetbrains.com/hc/en-us/community/posts/. Последний пост (я думаю, от парня из Resharper) в основном объясняет это   -  person Flydog57    schedule 25.01.2019


Ответы (1)


Добро пожаловать в Stack Overflow.

Предупреждение ReSharper Access to disposed closure должно появляться только тогда, когда отложенное выполнение LINQ фиксирует ссылку на закрытие, которое может быть удален до выполнения.

Так ли это здесь, зависит от того, какой ForEach метод вы вызываете. Если вы вызываете List.ForEach, значит, вы не составляете цепочку отложенного выполнения, поэтому fout, очевидно, будет действительным для каждого вызова. ReSharper определенно должен лучше разбираться в этом методе.

Но есть и другие ForEach методы, в том числе специальные, о которых ReSharper может не знать или которые на самом деле могут быть отложены. Если они хорошо написаны, они будут блокироваться до завершения, но я видел специальные ForEach методы расширения, которые этого не делают. Поскольку ReSharper не может знать наверняка, если код не сообщает об этом с помощью аннотации InstantHandle к параметру действия, он предупреждает вас.

Если вы работаете с _8 _ здесь я бы посоветовал вам отказаться от него в пользу старого доброго foreach утверждения. Для других расширений выясните, блокирует ли оно или есть вероятность того, что оно отложит выполнение при любых обстоятельствах. Observable.ForEach и person Corey    schedule 25.01.2019