1

I have a custom formatter to support my web calls, but a bug report shed some light on an issue. I was overriding the WriteToStreamAsync() method as such:

public override Task WriteToStreamAsync(Type type,
                                        object value,
                                        Stream writeStream,
                                        HttpContent content,
                                        TransportContext transportContext)
{
    return Task.Run(() =>
        {
            if (value == null) return;
            using (var sw = new StreamWriter(writeStream))
            {
                var serialized = _serializer.Serialize(value);
                sw.Write(serialized);
            }
        });
}

According to this post, the issue was that the using statement was causing the stream to close. The solution was to remove the using statement and use an explicit Flush() call, but it feels wrong to depend on the GC to dispose of the StreamWriter.

public override Task WriteToStreamAsync(Type type,
                                        object value,
                                        Stream writeStream,
                                        HttpContent content,
                                        TransportContext transportContext)
{
    return Task.Run(() =>
        {
            if (value == null) return;
            var sw = new StreamWriter(writeStream);
            var serialized = _serializer.Serialize(value);
            sw.Write(serialized);
            sw.Flush();
        });
}
  1. Is this a major concern?
  2. Is there a better (more "best practice") way of doing this?
gregsdennis
  • 7,218
  • 3
  • 38
  • 71

1 Answers1

1

Is this a major concern?

No, if the Stream survives the reader and it is clear, who is responsible for disposing the stream.

It is common in the .NET Framework, too. For example, if an Icon is created from a Stream, you must not dispose it (do not use the using construct when you create the icon) because it will be used by the created instance.

Is there a better (more "best practice") way of doing this?

  • If you create both the Stream and the StreamWriter in the same scope, the story is clear, you can dispose them.
  • If you get an already existing Stream, you cannot be sure that you are allowed to dispose the Stream. Do not close it unless the documentation is clear about that.
György Kőszeg
  • 17,093
  • 6
  • 37
  • 65