Обтекание потока внутри потока - будет ли правильно обернутый поток? - PullRequest
2 голосов
/ 01 августа 2011

Я не знаю, как это проверить, например:

using (var stream = new StreamWriter(someStream))
{
    stream.Write("");
}

будет ли это вести себя так:

using (var stream1 = someStream)
{
    using (var stream2 = new StreamWriter(stream1))
         stream.Write("");
}

или если бы я обернулся в GZipStream или любой другой поток ... будет ли первый пример располагать каждый нижележащий поток?

Обновление:

Наконец-то это поразило меня - просто сам реализовал класс Stream:

class MyStream : Stream
{
    // fake stream implementation

    protected override void Dispose(bool disposing)
    {
        Console.WriteLine("disposing in my class");
        base.Dispose(disposing);
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyStream stream = new MyStream();
        DoSomething(stream);
        stream.Dispose();

        Console.WriteLine("end of program");
    }

    private static void DoSomething(Stream stream)
    {
        using (var writer = new StreamWriter(stream))
        {
            Console.WriteLine("inside using statement");
        }

        Console.WriteLine("after writing");
    }
}

и результат:

inside using statement
disposing in my class
after writing
disposing in my class
end of program

Ответы [ 3 ]

2 голосов
/ 01 августа 2011

Нет, вы не можете полагаться на то, что он удаляет базовый поток для любых IDisposable объектов (хотя в случае StreamWriter это задокументировано).В общем случае не полагайтесь на это.

Вы должны использовать вложенные операторы using.

2 голосов
/ 01 августа 2011

Вы смешиваете две концепции здесь.

Основной вложен с использованием блоков, и во втором примере вы используете их правильно.

Вторая проблема - вложенные / упакованные / связанные одноразовые классы.В случае StreamWriter и Stream, Writer закроет Stream.Но вы не хотите этого знать, просто используйте шаблон использования.

Небольшой совет, следующий альтернативный макет легче читать и поддерживать.При добавлении GZipStream у вас будет 3+ вложенности с использованием блоков.

using (var stream1 = File.Create(...))
using (var stream2 = new StreamWriter(stream1))
{    
         stream2.Write("");
}
2 голосов
/ 01 августа 2011

Вызов close на самом верхнем потоке каскадно спускается и закрывает их все, но это не рекомендуется, потому что трудно следить за тем, что открыто, а что нет. Как сказал другой ответчик, используйте блоки использования религиозно.

Надеюсь, это поможет!

...