How to apply using-pattern with System.Func? - c#

Usually I use a memory stream with the well known using pattern.
using(var mem = new MemoryStream(blob))
{
foo(mem);
}
No imagine a function bar(Func<Stream>) defined in a client library that I have to use. I could call it like this
bar(() => new MemoryStream(blob));
but then nobody is disposing the stream properly. How to work around it? Should Func be used with IDisposable types at all?

It seems like a poorly designed library.
If you know for a fact that the library does not dispose of the stream and it doesn't hold the Func<Stream> for later use, then you can do this:
using(var mem = new MemoryStream(blob))
{
bar(() => mem);
}

Related

C# 8 Using Declaration Scope Confusion

With the new C# 8 Using Declaration Syntax, what is containing scope of a second consecutive using statement?
TL;DR
Previous to C# 8, having a consecutive using statement like:
using(var disposable = new MemoryStream())
{
using(var secondDisposable = new StreamWriter(disposable))
{}
}
would expand to something like the following (My Source):
MemoryStream disposable = new MemoryStream();
try {
{
StreamWriter secondDisposable = new StreamWriter(disposable);
try{
{}
}
finally {
if(secondDisposable != null) ((IDisposable)secondDisposable).Dispose();
}
}
}
finally {
if(disposable != null) ((IDisposable)disposable).Dispose();
}
I know that there are two other possible expansions but they all are roughly like this
After upgrading to C# 8, Visual studio offered a Code Cleanup suggestion that I'm not certain I believe is an equivalent suggestion.
It converted the above consecutive using statement to:
using var disposable = new MemoryStream();
using var secondDisposable = new StreamWriter(disposable);
To me this changes the second's scope to the same scope as the first. In this case, It would probably coincidentally dispose of the streams in the correct order, but I'm not certain I like to rely on that happy coincidence.
To be clear on what VS asked me to do: I first converted the inner (which made sense because the inner was still contained in the outer's scope). Then I converted the outer (which locally made sense because it was still contained in the method's scope). The combination of these two clean ups is what I'm curious about.
I also recognize that my thinking on this could be slightly (or even dramatically) off, but as I understand it today, this doesn't seem correct. What is missing in my assessment? Am I off base?
The only thing I can think of is that there is some sort of an implicit scope inserted in the expansion for everything following a declaration statement.
In this case, It would probably coincidentally dispose of the streams in the correct order, but I'm not certain I like to rely on that happy coincidence.
From the spec proposal:
The using locals will then be disposed in the reverse order in which they are declared.
So, yes, they already thought about it and do the disposal in the expected order, just as chained using statements would before it.
To Illustrate the Daminen's answer; When you have a method something like;
public void M()
{
using var f1 = new System.IO.MemoryStream(null,true);
using var f2 = new System.IO.MemoryStream(null,true);
using var f3 = new System.IO.MemoryStream(null,true);
}
IL converts it into;
public void M()
{
MemoryStream memoryStream = new MemoryStream(null, true);
try
{
MemoryStream memoryStream2 = new MemoryStream(null, true);
try
{
MemoryStream memoryStream3 = new MemoryStream(null, true);
try
{
}
finally
{
if (memoryStream3 != null)
{
((IDisposable)memoryStream3).Dispose();
}
}
}
finally
{
if (memoryStream2 != null)
{
((IDisposable)memoryStream2).Dispose();
}
}
}
finally
{
if (memoryStream != null)
{
((IDisposable)memoryStream).Dispose();
}
}
}
Which is same as nested using statements
you can check from here: https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQMwAJboMLoN7LpGYZQAs6AsgBQCU+hxTUADOgG4CGATugGZx0AXnQA7AKYB3THAB0ASQDysyuIC2Ae24BPAMoAXbuM5rqogK4AbSwBpD58bQDcTRkyKsOPfjGFipMgrKqpo6BkYmZla29o5Obu6eXLx8GCIS0lBySirqWnqGxqYW1nbcDs4JAL7IVUA===
I'd like to see the real function that's using this. The compiler won't change scope or sequence of allocations or disposals willy-nilly. If you have a method like:
void foo()
{
using(var ms = new MemoryStream())
{
using(var ms2 = new MemoryStream())
{
/// do something
}
}
}
Then the Dispose() order doesn't matter, so it's safe for the compiler to arrange things however it sees fit. There may be other cases where the order is important, and the compiler should be smart enough to recognize that. I wouldn't file that under "coincidence" so much as "good AST analysis."

Do i need to Dispose Stream when i Pass it to IDisposable class?

I wrote a piece of code. I want to make sure that I am Disposing an Object in right way.
I have a Disposable Class like this
Which is used to read some data from unmanaged resource.
class MyFileReader : IDisposable
{
private readonly FileStream _stream;
public MyFileReader(FileStream stream)
{
_stream = stream;
}
public void Dispose()
{
_stream.Dispose();
}
}
Currently in my program I Dispose objects like this.
using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (MyFileReader reader = new MyFileReader(stream))
{
//...
}
}
This seems ok to me. later I have noticed That Classes are passed by reference so maybe if I dispose one of them there is no need to dispose the other one.
My question is Can i Do Something like this?
using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
MyFileReader reader = new MyFileReader(stream);
// Remove IDisposable from MyFileReader and stream will close after using.
}
Or this one?
FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
// stream will close after using.
using (MyFileReader reader = new MyFileReader(stream))
{
//...
}
Yes, you can write code like that.
But, no, you should not do that.
Your class looks like on of XxxxReader classes that by convention own the stream they read from. As result your MyFileReader class is expected to dispose the inner stream. You also normally expected to dispose each and every disposable object when you know that such object's lifetime is over.
Note that sometimes it lead to multiple Dispose calls on some objects (which should be expected by implementations of IDisposable). While it may sometimes lead to Code Analysis warning it is better than missing Dispose calls if one routinely tries to "optimize" number of calls to Dispose by skipping some.
Alternative approach is to expose method that reads content which by convention is not expected to take ownership of stream/reader like:
using(stream....)
{
var result = MyFileReader.ReadFrom(stream);
}
If MyFileReader is accessing some unmanaged resource and you need the Disponse method to be called explicitly after this code block, then you have to stick with your current implementation.
In the second implementation, the Dispose method will not be called for the MyFileReader object. (until you probably call it in the destructor which you don't know when that would be called)
If you do not like the nested using, then you can probably go with the second alternative and in the Dispose() method implementation of MyFileReader class, explicitly dispose the Stream. If this stream is only use by MyFileReader, then this is a good practice to have MyFileReader manage its lifecycle and dispose it.
Many framework stream-wrapping classes have constructor overloads with leaveOpen parameter that controls stream disposing behavior.
Examples include StreamReader, BinaryReader, GZipStream.
There is also property approach, SharpZipLib example:
using (var zip = new ZipInputStream(stream) { IsStreamOwner = false }) { ... }

Generic Stream that can call Dispose() method for another object after closing

Here is a very simple example how I can return a Stream to ASP.NET MVC:
public ActionResult DownloadData(...)
{
using(var lib = new SomeLibrary())
{
// do some stuff...
var stream = new MemoryStream();
lib.SaveAs(stream);
stream.Position = 0;
return File(stream, "contenttype", "filename");
}
}
The problem is that MemoryStream will be allocated in large heap object area and on 32 bit system it will cause OutOfMemoryException quite soon because of RAM fragmentation that will prevent allocation of a large memory block even if there is enough memory. On 64 bit systems this method is also quite slow.
What I want is just return a stream, similar to this
public ActionResult DownloadData(...)
{
using(var lib = new SomeLibrary())
{
// do some stuff...
return File(lib.Stream, "contenttype", "filename");
}
}
However then the using statement will call .Dispose() before my data is returned. If I remove the using statement completely, then the library will lock resources until garbage collector clean up memory.
I think the best solution will be to use a generic Stream that just copy the source stream and call .Dispose() at the end:
public ActionResult DownloadData(...)
{
var lib = new SomeLibrary()
try
{
// do some stuff...
var stream = new CopyStream(lib.Stream, lib);
return File(stream, "contenttype", "filename");
}
catch(Exception)
{
lib.Dispose();
throw;
}
}
The generic stream should call .Dispose() for the second parameter lib after closing.
Is there any existing implementation for such a Stream in .NET or NuGet?
Maybe i did not understand exactly what you need but in your case, there is no need to dispose the stream by yourself (with an explicit Dispose() call or with the using keyword).
The File helper method coming from ASP MVC controller is designed to return streams : It creates a FileStreamResult that is in charge of disposing the encapsulated stream and will do it when its job is done.
On this topic, you can find a far better and more detailed answer of Darin Dimitrov in here.

C# "using" blocks

I've got something like the code below...someone here mentioned that the WebClient, Stream, and StreamReader objects could all benefit from using blocks. Two easy questions:
1: How would this little snippet look with using blocks? I've no problem with doing my own research so resource links are fine but it'd be quicker and easier to just see an example and I'll understand it from that.
2: I'd like to get in the habit of good coding standards, would help if I knew a little about the reasons why using blocks are better...is it just so you don't have to worry about closing or are there more reasons? Thanks!
WebClient client = new WebClient();
Stream stream = client.OpenRead(originGetterURL);
StreamReader reader = new StreamReader(stream);
JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
string encryptionKey = (string)jObject["key"];
string originURL = (string)jObject["origin_url"];
stream.Close()
reader.Close()
using (var client = new WebClient())
using (var stream = client.OpenRead(originGetterURL))
using (var reader = new StreamReader(stream))
{
var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
var encryptionKey = (string)jObject["key"];
var originURL = (string)jObject["origin_url"];
}
or simply:
using (var client = new WebClient())
{
var json = client.DownloadString(originGetterURL);
var jObject = Newtonsoft.Json.Linq.JObject.Parse(json);
var encryptionKey = (string)jObject["key"];
var originURL = (string)jObject["origin_url"];
}
using (WebClient client = new WebClient())
{
// do work
}
Provides a convenient syntax that ensures the correct use of IDisposable objects.
From MSDN: using Statement (C# Reference)
As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.
using(WebClient client = new WebClient()) {
}
is the same as
WebClient client;
try {
client = new WebClient();
} finally {
if(client != null) {
client.Dispose();
}
}
A lot easier to use using
Its simple :
Using *using* is not "good practice" as such, more a short way (syntactic sugar) of disposing objects that you should be disposing. Things like Files, Connections to a Database and in your case a network.
You would do something like:
using(WebClient we = new WebClient))
{
//do something with 'we' here
}
This is basically just a shortcut for using the variable we normally and then calling we.Dispose() which does a clean up.
Syntax :
using (<Any class that Implements IDisposable>)
{
//use the class
}
Other SO questions you should see:
What is the relationship between the using keyword and the IDisposable interface?
using various types in a using statement (C#)
using {} blocks simply call Dispose() at the closing brace--or rather, tell the Garbage Collector that it can dispose of the object. You'd use it like:
using (WebClient client = new WebClient())
{
Stream stream = client.OpenRead(originGetterURL); StreamReader reader = new StreamReader(stream);
JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine()); string encryptionKey = (string)jObject["key"]; string originURL = (string)jObject["origin_url"];
stream.Close() reader.Close()
} // 'client' instance gets disposed here
Something like this:
using(WebClient client = new WebClient())
using(Stream stream = client.OpenRead(originGetterURL))
StreamReader reader = new StreamReader(stream) {
JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
string encryptionKey = (string)jObject["key"];
string originURL = (string)jObject["origin_url"];
}
As for why using blocks are good, and better than manually calling Dispose... image if any of the code in that using block threw an exception before you hit the lines where you close everything? You'd essentially leak whatever unmanaged resource the IDisposable object is managing under the hood. using ensures that Dispose is called correctly, even in the face of an exception (by essentially injecting the appropriate try/finally block).
When possible (i.e., you don't have to preserve the lifetime of some IDisposable across scopes), you should leverage using blocks if for no other reason than they reduce the amount of boilerplate code you have to write in order to ensure your own code is safe and correct.
#Darin's answer shows the code. The reason they are good is that using blocks cause the compiler to spit out code that will automatically call "Dispose" on the object (to have it immediately release any resources it may be using) before exiting the block - even if an exception gets thrown within with the block
using is equivalent to try.. finally so the disposer will run even if an exception is thrown within the block.
There are 2 reasons for using-blocks:
They look good
The code inside the block often could throw exceptions. So you wold need try-finally
In the end a using-block e.g.
using (Somthing somthing=...)
{
DoActions(somthing);
}
is identical to the followin contstruct:
{Somthing somthing=...
try
{
DoActions(somthing);
}
finally
{
somthing.Dispose();
}
}//the outer bracket limits the variable

Can you keep a StreamReader from disposing the underlying stream?

Is there a way to do this:
this.logFile = File.Open("what_r_u_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);
using(var sr = new StreamReader(this.logFile))
{
// Read the data in
}
// ... later on in the class ...
this.logFile = File.Open("what_r_u_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);
using(var sw = new StreamWriter(this.logFile))
{
// Write additional data out...
}
Without having to open the file twice?
I can't seem to make the StreamReader not-dispose my stream. I don't want to just let it go out of scope, either. Then the garbage collector will eventually call the Dispose, killing the stream.
.NET 4.5 will finally fix this problem with a new constructors on StreamReader and StreamWriter that take a leaveOpen parameter:
StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
StreamWriter(Stream stream, System.Text.Encoding encoding, int bufferSize, bool leaveOpen)
I don't want to just let it go out of scope, either. Then the garbage collector will eventually call the Dispose, killing the stream.
Garbage collector will call the Finalize method (destructor), not the Dispose method. The finalizer will call Dispose(false) which will not dispose the underlying stream. You should be OK by leaving the StreamReader go out of scope if you need to use the underlying stream directly. Just make sure you dispose the underlying stream manually when it's appropriate.
You could use the NonClosingStreamWrapper class from Jon Skeet's MiscUtil library, it serves exactly that purpose
You could create a new class which inherits from StreamReader and override the Close method; inside your Close method, call Dispose(false), which as Mehrdad pointed out, does not close the stream. Same applies to StreamWriter, of course.
However, it seems like a better solution would simply be to hold onto the StreamReader and StreamWriter instances as long as you may need them. If you're already planning to keep the stream open, you might as well keep a StreamReader and StreamWriter open also. If you use StreamWriter.Flush and Stream.Seek correctly, you should be able to make this work even when doing both reading and writing.
Just remove the using-Block. You don't have to Dispose() the StreamReader if you don't want to do Dispose() the stream, I think.
Use another constructor overload where you can specifu a "leaveOpen" parameter to "true"
I always use something like this:
(it also uses the leaveOpen argument)
public static class StreamreaderExtensions
{
public static StreamReader WrapInNonClosingStreamReader(this Stream file) => new StreamReader(file, Encoding.UTF8, true, 1024, true);
}
Usage:
using (var reader = file.WrapInNonClosingStreamReader())
{
....
}
I was able to use leaveOpen parameter without specifying all the constructor params (encoding or buffer size) like this:
using var streaReader = new StreamReader(stream, leaveOpen: true);
Close it yourself in a try/finally clause when you're done with it.
var sr = new StreamReader();
try {
//...code that uses sr
//....etc
}
finally
{
sr.Close();
}

Categories