|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Behaviour of streams in and out of scopeI was wondering what happens to streams when they're passed between objects, because my understanding of them is that they're effectively a pointer to a data structure (or a location within it), rather than a copy of the structure itself. E.g. a file stream is not a copy of the file (as a string would be, for example, if you read it all into a string) but a means of accessing the file. So that got me thinking about the scope behaviour of the stream. Sample code may make it easier to see what I mean: namespace Streams_in_scope { class Program { static void Main(string[] args) { // instantiated object, with local instance variable returned as stream. You'd think this would work. LocalScope testClass = new LocalScope(); Stream foo = testClass.foo; // static class, with method which returns stream. How this will work I don't know - there's no actual instance of the object, so the stream has nowhere to "come from" if it isn't fully populated and returned as a whole collection of bytes. Stream bar = StaticLocalScope.GetFoo(); // class with an external source of data, returned as a stream. // Is it a pointer to the file? Or as a pointer to a file reference contained within the class which goes out of scope? // will the stream cease to exist when leaving scope, when GC runs, or never? Stream foobar; try { foobar = ExternalFileStream.GetFoobar(); } catch { } } } class LocalScope { private string _foo = "and now is the time for all good men to come to the aid of the party."; public Stream foo { get { Stream fooStream = new MemoryStream(); StreamWriter sw = new StreamWriter(fooStream); sw.Write(_foo); return fooStream; } } } static class StaticLocalScope { public static Stream GetFoo() { string _foo = "and now is the time for all good men to come to the aid of the party."; Stream fooStream = new MemoryStream(); StreamWriter sw = new StreamWriter(fooStream); sw.Write(_foo); return fooStream; } } static class ExternalFileStream { public static Stream GetFoobar() { Stream fs = File.OpenRead(@"c:\windows\system32\drivers\etc\hosts"); return fs; } } } There I have a few methods, each of which returns a stream. The first I would expect to work "properly" - in that the object which contains the data the stream points to continues to exist. Thus, the stream should keep working. The second, I'm not sure of. How does reference counting work on a static class, which is therefore not instantiated and so can have no references to an instance? Will the stream work? Won't it? Will garbage collection come along and remove the underlying data but leave me with a Stream pointing to either null, or some random block of RAM? The third, I'm even less sure of. It's a static class, which also goes out of scope at the end of the try block. It should DEFINITELY be collectable. Will my returned FileStream be a stream on the file (in which case it should work independent of GC activity), or on a representation of that file (a filehandle, if you like) in the scope of my ExternalFileStream class (in which case, the filehandle could reasonably be collected by GC and I'm left again with a FileStream to a filehandle which doesn't exist. Anyone know the answer? Kev Kevin,
>I was wondering what happens to streams when they're passed between objects, That's true for any reference type, including Streams.>because my understanding of them is that they're effectively a pointer to a >data structure (or a location within it), rather than a copy of the structure >itself. >E.g. a file stream is not a copy of the file (as a string would be, A string is also a reference type.>for example, if you read it all into a string) but a means of accessing the >file. >The second, I'm not sure of. How does reference counting work on a static It doesn't matter where you instantiate the stream. The fact that it>class, which is therefore not instantiated and so can have no references to >an instance? comes from a method in a static class is totally irrelevant (so all three of your code snippets will work fine). The only thing that matters is that you keep a reference to the stream object itself. As long as you do, the object will be valid and not collected by GC. >Will garbage collection come No, that never happens. GC only cleans up objects that aren't>along and remove the underlying data but leave me with a Stream pointing to >either null, or some random block of RAM? referenced anymore (or only referenced by other objects eligible for collection). GC will not null out references or make them invalid. >The third, I'm even less sure of. It's a static class, which also goes out Since there's no instance of the static class, there's nothing to>of scope at the end of the try block. It should DEFINITELY be collectable. collect. And scope has nothing to do with it. In summary, you worry too much :) Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. |
|||||||||||||||||||||||