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
Related
Seeking best inputs on correct usage of C# using statement. Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?
Although the code snippet is different from what I feel that the using statement should be in ProcessFileAndReturnNumberFromStream() method of 'Business' class.
Why is it an uncommon practice to use using statement on object passed via parameter? Please correct or elaborate on the flaw?
using System;
using System.IO;
class Data
{
public double? GetNumberFromStream(StreamReader sr)
{
double? number;
try
{
using (sr)
{
number = Convert.ToDouble(sr.ReadToEnd());
return number;
}
}
finally
{
number = null;
}
}
}
class Business
{
public double? ProcessFileAndReturnNumberFromStream()
{
string fileName = "Test.txt";
StreamReader sr = new StreamReader(fileName);
Data dat = new Data();
return dat.GetNumberFromStream(sr);
}
}
class GUI
{
static void Main()
{
Business bus = new Business();
double? number = bus.ProcessFileAndReturnNumberFromStream();
Console.WriteLine(number);
Console.ReadKey();
}
}
Please help.
Thanks
If a method is passed an object that implements IDisposable, it's usually the responsibility of the caller to manage the lifetime of that object, rather than the callee.
public double? ProcessFileAndReturnNumberFromStream()
{
string fileName = "Test.txt";
Data dat = new Data();
using (StreamReader sr = new StreamReader(fileName))
{
return dat.GetNumberFromStream(sr);
}
}
The caller that is passing the instance of IDisposable should be the one to use the using statement. If the callee uses it, the object will be disposed while outside the immediate control of the caller who 'owns' the object.
Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?
You can, but it's generally odd to do so. Usually whatever is creating the StreamReader would be expecting to "own" it and dispose of it when they're done with it. It would be more usual for your ProcessFileAndReturnNumberFromStream method to be:
using (StreamReader sr = new StreamReader(fileName))
{
Data dat = new Data();
return dat.GetNumberFromStream(sr);
}
(Although I'd personally use File.OpenText instead of explicitly constructing the StreamReader.)
Your GetNumberFromStream method would then not need the using statement. It also doesn't need the try/finally block at all - it's an odd implementation all round, given that it will never return null, either...
It's also odd that you're creating a new instance of Data and then doing nothing with it - as your GetNumberFromStream method doesn't use an instance variables or override a base class method, you should consider making it static.
Such API would be extremely troublesome.
You would never know whether or not the object passed to a method is disposed inside the method or not. Thus, if this is you who create the object and pass it there, you would also never know whether or not you should dispose the object you have just created and passed to the method or not.
I guess then, while this is technically possible, it would promote the bad programming style.
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."
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);
}
Is it true that if i use the following, it will take less resources and the cleanup will be faster?
using (TextReader readLogs = File.OpenText("C:\\FlashAuto\\Temp\\log.txt"))
{
//my stuff
}
as compared to:
TextReader readLogs = new StreamReader("C:\\FlashAuto\\Temp\\log.txt");
//my stuff
readLogs.Close();
readLogs.Dispose();
The difference between those examples isn't performance, but exception safety. using creates a try...finally block in the background.
A using statement of the form:
using (ResourceType resource = expression) embedded-statement
corresponds to the expansion:
{
ResourceType resource = expression;
try {
embedded-statement
}
finally {
// Dispose of resource
}
}
For reference type the disposing happens via:
finally {
if (resource != null) ((System.IDisposable)resource).Dispose();
}
From ECMA-344 C# Language Specification 4th Edition
You also don't need to call both Close and Dispose. Those functions are equivalent.
The first sample is short-hand for:
TextReader readLogs = File.OpenText("C:\\FlashAuto\\Temp\\log.txt");
try
{
// My stuff
}
finally
{
if (readLogs != null)
{
((IDisposable)readLogs).Dispose();
}
}
Its not that its quicker, its that readLogs will be cleaned up even if an exception occurrs which won't happen in your second example.
See using Statement (C# Reference) for more information.
There is no need to call both Close and Dispose, internally the Close method does the same work as the Dispose method (its just renamed because developers are used to having a method called Close).
Update: There is also no difference between calling File.OpenText and new StreamReader - internally File.OpenText just creates and returns a new instance of StreamReader.
I am returning the variable I am creating in a using statement inside the using statement (sounds funny):
public DataTable foo ()
{
using (DataTable properties = new DataTable())
{
// do something
return properties;
}
}
Will this Dispose the properties variable??
After doing this am still getting this Warning:
Warning 34 CA2000 : Microsoft.Reliability : In method 'test.test', call System.IDisposable.Dispose on object 'properties' before all references to it are out of scope.
Any Ideas?
Thanks
If you want to return it, you can't wrap it in a using statement, because once you leave the braces, it goes out of scope and gets disposed.
You will have to instantiate it like this:
public DataTable Foo()
{
DataTable properties = new DataTable();
return properties;
}
and call Dispose() on it later.
Yes, it will dispose it - and then return it. This is almost always a bad thing to do.
In fact for DataTable, Dispose almost never does anything (the exception being if it's remoted somewhere, IIRC) but it's still a generally bad idea. Normally you should regard disposed objects as being unusable.
Supposedly, this is the pattern for a factory method that creates a disposable object. But, I've still seen Code Analysis complain about this, too:
Wrapper tempWrapper = null;
Wrapper wrapper = null;
try
{
tempWrapper = new Wrapper(callback);
Initialize(tempWrapper);
wrapper = tempWrapper;
tempWrapper = null;
}
finally
{
if (tempWrapper != null)
tempWrapper.Dispose();
}
return wrapper;
This should guarantee that if the initialization fails, the object is properly disposed, but if everything succeeds, an undisposed instance is returned from the method.
MSDN Article: CA2000: Dispose objects before losing scope.
Yes. Why are you using the using keyword on something you don't want disposed at the end of the code block?
The purpose of the using keyword is to dispose of the object.
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
The point of a using block is to create an artificial scope for a value/object. When the using block completes, the object is cleaned up because it is no longer needed. If you really want to return the object you are creating, than it is not a case where you want to use using.
This will work just fine.
public DataTable foo ()
{
DataTable properties = new DataTable();
// do something
return properties;
}
Your code using the using keyword expands to:
{
DataTable properties = new DataTable();
try
{
//do something
return properties;
}
finally
{
if(properties != null)
{
((IDisposable)properties).Dispose();
}
}
}
Your variable is being disposed by nature of how using works. If you want to be able to return properties, don't wrap it in a using block.
The other responses are correct: as soon as you exit the using block, your object is disposed. The using block is great for making sure that an object gets disposed in a timely manner, so if you don't want to rely on the consumers of your function to remember to dispose the object later, you can try something like this:
public void UsingDataContext (Action<DataContext> action)
{
using (DataContext ctx = new DataContext())
{
action(ctx)
}
}
This way you can say something like:
var user = GetNewUserInfo();
UsingDataContext(c => c.UserSet.Add(user));