This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What is the C# Using block and why should I use it?
My question: Is using using(a){do something with a} better than declaring 'a' and using it that way. ie: more secure, faster, ...
see examples for clarification.
Example 1:(without using)
StreamWriter sw;
string line;
sw = new StreamWriter("D:\\NewCon.xml");
sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
sw.WriteLine("<config>");
for (int i = 0; i >=36; i++)
{
line = "";
line = "<" + xmlnodes[i] + ">";
line += vals[i];
line += "</" + xmlnodes[i] + ">";
sw.WriteLine(line);
}
sw.WriteLine("</config>");
sw.Close();
sw.Dispose();
Example 2:(with using)
string line;
using (sw = new StreamWriter("D:\\NewCon.xml"))
{
sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
sw.WriteLine("<config>");
for (int i = 0; i >= 36; i++)
{
line = "";
line = "<" + xmlnodes[i] + ">";
line += vals[i];
line += "</" + xmlnodes[i] + ">";
sw.WriteLine(line);
}
sw.WriteLine("</config>");
}
using(a){do something with a}
This means that when the code block is done with a, the program will call a.Dispose. You know that even in the event of an exception, a will have Dispose called. It is essentially doing:
var a = IDisposable_Something;
try{.....}finally{a.Dispose();}
Is it more secure...not really, but that's not the point. The point of it is to make sure that resources which need to be cleaned up are done as soon as the program is finished with them.
So the problem with your first example, is that if somewhere along the line an exception is thrown, it won't make it to the Dispose() method. The second will. You always want to ensure Dispose gets called if it is there, because there is the possibility that the IDisposable classs won't have been written correctly, and it won't have the code to make sure that the unmanaged resources are cleaned up even if Dispose() isn't called (this is generally done in a finalizer). LInk to Dispose Pattern.
The only time I have ever seen where implementing using can be tricky is with the WCF service proxy (and you can work around that issue). There is a bug where if the proxy throws an exception at times, it will cause another exception in the Dispose() method.
http://blogs.msdn.com/b/jjameson/archive/2010/03/18/avoiding-problems-with-the-using-statement-and-wcf-service-proxies.aspx
Other than that you should generally try and put an IDisposable object in a using statement.
If an exception is thrown in your first example then the resource won't be disposed.
Using using ensures that the resource is disposed even when an exception is thrown.
Example 1 should never be done. If an exception is thrown, your Dispose() call will never happen, which could be bad. using guarantees execution of Dispose(). The only good alternative to Example 1 (besides using) would be:
var iDisposableObject = new YourDisposableConstructor();
try
{
// some code
}
finally
{
iDisposableObject.Dispose();
}
First of all, the code in example 1 should be wrapped in a try/finally block in order to be functionally equivalent with the code in example 2.
That said, I've always liked 'using' blocks for code like this. I think it generally leads to more readable code. As far as security or performance, you're not going to see much difference between example 1 and example 2, providing you use a try/finally block in the first example!
Using using is safer because you have guaranted resources releasing declared in using(...) braces even when any error or unexpected exit occured.
Added to previous answers, and the most importabt part, if an exception occurs, calling dispose() is guaranteed.
It's more secure in the sense that you tend not to forget to dispose of resources, especially in the case of an exception (your code currently doesn't catch any).
It's more succinct and idiomatic since you use less lines of code and the intend of your code becomes much clearer.
So this:
StreamWriter sw;
try
{
sw = new StreamWriter("D:\\epkDATA\\NewCon.xml");
...
}
finally
{
sw.Dispose();
}
is equivalent to:
using(StreamWriter sw = new StreamWriter("D:\\epkDATA\\NewCon.xml"))
{
...
}
if ClassA inherit from IDisposing.A "using" pattern is equal to following:
IDisposable iDisposableObject = new YourDisposableConstructor();
try
{
// some code
}
finally
{
iDisposableObject.Dispose();
}
so we'd better use the using pattern
Related
I'm trying to concatenate some data within a foreach iterator within a using block. Unfortunately, for some reason, any statements I insert into (or after) the using block after the foreach fail to fire.
Source:
static void sensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (var depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame == null)
return;
short[] bits = new short[depthFrame.PixelDataLength];
string bitString = "0";
depthFrame.CopyPixelDataTo(bits);
foreach (var bit in bits)
{
bitString += bit.ToString();
Console.Write("This fires.");
}
Console.Write("This never fires and I don't know why.");
Program.Broadcast(bitString); //this also fails to fire.
}
Console.Write("This never fires either.");
}
Looking at the code there's no obvious reason for it not to work. I doubt it has anything to do with the using() block.
Maybe check the following:
Is your foreach loop terminating? How many elements are in the bits array and how many times is "This Fires" being written out?
The console output may be getting buffered and you aren't seeing anything printed until it is flushed. What happens if you replace Console.Write() with Console.WriteLine()?
The only other way execution could be breaking out of the loop without reaching Program.Broadcast(bitString) is if an exception is being thrown. Try wrapping the whole function in a try/catch/finally construct and print any exceptions that occur, and possibly a message in the finally block that should be printed no matter what happens.
Hope that helps.
Maybe the foreach takes too long? try using StringBuilder.
StringBuilder bitString = new StringBuilder("0");
depthFrame.CopyPixelDataTo(bits);
foreach (var bit in bits)
{
sb.Append(bit.ToString();
}
Program.Broadcast(bitString.ToString());
I was searching the web for a while now. But didn't find any clear answer to my question. Whether when connecting to a database I should use "using" or I can just go with try-catch-finally? What I mean is:
I don't know if I should call the dispose method each time I finish interacting with the database or just close the connection.
static public List<Category> GetAll()
{
List<Category> CategoryList;
try
{
BaseDAO.Dbconn.Open();
BaseDAO.SetCommand(BaseDAO.CommandAction.Read, "SELECT * FROM Categories");
CategoryList = new List<Category>();
using (DbDataReader reader = BaseDAO.Dbcmd.ExecuteReader())
{
while (reader.Read())
{
int ID = reader.GetInt32(reader.GetOrdinal("CategoryID"));
string Name = reader.GetString(reader.GetOrdinal("CategoryName"));
string Description = reader.GetString(reader.GetOrdinal("Description"));
CategoryList.Add(new Category(ID, Name, Description));
}
}
return CategoryList;
}
catch (Exception ex)
{
BaseDAO.Dbconn.Dispose();
throw ex;
}
finally { BaseDAO.Dbconn.Close(); }
}
The "Dbconnection" is static not sure if this is a good solution as well...
I am getting to know ADO and just wanted to know what's the best answer for this kind of question.
It doesn't make any difference - whatever you prefer. The using clause gets turned into a try-finally by the compiler anyway.
EDIT I just noticed you are only calling Dispose if an exception occurs. You should move this into the finally clause as well. Dispose will call Close, so you don't need to specifically call it if you don't want to.
Further edit Given that, as you say, your DbConnection is static, then you don't want to call Dispose, but you do need to call Close. However, there should not be any need to use a static DbConnection - connection pooling will take care of efficiently handling the connections. Your code should create a new connection instance every time.
Reference: Using Statement C#.
The using statement allows the programmer to specify when objects that use resources should release them.
The object provided to the using statement must implement the
IDisposable interface. This interface provides the Dispose method,
which should release the object's resources.
A using statement can be exited either when the end of the using statement is reached or if an exception is thrown and control leaves the statement block before the end of the statement.
Reference : Example
As per Code Project, the .NET CLR converts
using (MyResource myRes = new MyResource())
{
myRes.DoSomething();
}
to:
{
// limits scope of myRes
MyResource myRes= new MyResource();
try
{
myRes.DoSomething();
}
finally
{
// Check for a null resource.
if (myRes!= null)
// Call the object's Dispose method.
((IDisposable)myRes).Dispose();
}
}
Calling Dispose is equivalent to calling Close in most (if not all) DbConnection implementations, so there's no need to call the former if you are already calling the latter. Just make sure you do so in a finally in case there's an exception.
using(SomeClass x = new SomeClass("c:/temp/test.txt"))
{
...
}
Inside the using block, all is fine with treating exceptions as normal. But what if the constructor of SomeClass can throw an exception?
Put your using into the try catch f.e.
try
{
using(SomeClass x = new SomeClass("c:/temp/test.txt"))
{
...
}
}
catch(Exception ex)
{
...
}
Yes, this will be a problem when the constructor throws an exception. All you can do is wrap the using block within a try/catch block. Here's why you must do it that way.
using blocks are just syntactic sugar and compiler replaces each using block with equivalent try/finall block. The only issue is that the compiler does not wrap the constructor within the try block. Your code after compilation would have following conversion in the IL.
//Declare object x of type SomeClass.
SomeClass x;
//Instantiate the object by calling the constructor.
x = new SomeClass("c:/temp/test.txt");
try
{
//Do some work on x.
}
finally
{
if(x != null)
x.Dispose();
}
As you can see from the code, the object x will not be instantiated in case when the constructor throws an exception and the control will not move further from the point of exception raise if not handled.
I have just posted a blog-post on my blog on this subject last night.
I'm just now wondering why C#
designers did not wrap object
construction within the try block
which according to me should have been
done.
EDIT
I think I found the answer why C# does not wrap object construction into try block generated in place of the using block.
The reason is simple. If you wrap both declaration and instantiation within the try block then the object would be out of scope for the proceeding finally block and the code will not compile at because, for finally block the object hardly exists. If you only wrap the construction in the try block and keep declaration before the try block, even in that case the it will not compile since it finds you're trying to use an assigned variable.
I threw a quick test program together to check this, and it seems that the Dispose method does not get called when an exception is thrown in the constructor;
class Program
{
static void Main(string[] args)
{
try
{
using (OtherClass inner = new OtherClass())
{
Console.WriteLine("Everything is fine");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.Read();
}
}
class OtherClass : IDisposable
{
public OtherClass()
{
throw new Exception("Some Error!");
}
void IDisposable.Dispose()
{
Console.WriteLine("I've disposed my resources");
}
}
Output :
Some Error!
If you don't throw the exception..
Output :
Everything is fine
I've disposed my resources
Presumably this is because the object was never created, so there's nothing to call Dispose on.
I'm not sure what would happen if the constructor had already allocated some resources which would normally require a proper clean up through Dispose and the exception occurred afterwards though.
This should not be a problem with a well-designed class. Remember the overall question:
public class HoldsResources : IDisposable
{
public HoldsResources()
{
// Maybe grab some resources here
throw new Exception("whoops");
}
}
using (HoldsResources hr = new HoldsResources())
{
}
So, the question is, what should you do about the resources allocated by the HoldsResources constructor before it threw an exception?
The answer is, you shouldn't do anything about those resources. That's not your job. When it was decided that HoldsResources would hold resources, that brought the obligation to properly dispose of them. That means a try/catch/finally block in the constructor, and it means proper implementation of IDisposable to dispose of those resources in the Dispose method.
Your responsibility is to use the using block to call his Dispose method when you're through using the instance. Nothing else.
When you get a hold of resources in the ctor that are not subject to garbage collection, you have to make sure to dispose of them when things go south.
This sample shows a ctor which will prevent a leak when something goes wrong, the same rules apply when you allocate disposables inside a factory method.
class Sample
{
IDisposable DisposableField;
...
public Sample()
{
var disposable = new SomeDisposableClass();
try
{
DoSomething(disposable);
DisposableField = disposable;
}
catch
{
// you have to dispose of it yourself, because
// the exception will prevent your method/ctor from returning to the caller.
disposable.Dispose();
throw;
}
}
}
Edit: I had to change my sample from a factory to a ctor, because apparantly it wasn't as easy to understand as I hoped it would be. (Judging from the comments.)
And of course the reason for this is: When you call a factory or a ctor, you can only dispose of its result. When the call goes through, you have to assume that everything's okay so far.
When calling a ctor or factory you don't have to do any reverse-psychoanalysis to dispose of anything you can't get hold of anyways. If it does throw an exception, it is in the factories/ctor's responsibility to clear anything half-allocated before re-throwing the exception.
(Hope, this time, it was elaborate enough...)
I've got code that looks like this because the only reliable way for me to check if some data is an image is to actually try and load it like an image.
static void DownloadCompleted(HttpConnection conn) {
Image img;
HtmlDocument doc;
try {
img = Image.FromStream(conn.Stream);
} catch {
try {
doc = new HtmlDocument();
doc.Load(conn.Stream);
} catch { return; }
ProcessDocument(doc);
return;
}
ProcessImage(img);
return;
}
Which looks down right terrible!
What's a nice way of handling these situations? Where you're basically forced to use an exception like an if statement?
Your logical structure is
if( /* Loading Image Fails */ )
/* Try Loading HTML */
so I would try to make the code read that way. It would probably be cleanest (though admittedly annoyingly verbose) to introduce helper methods:
bool LoadImage()
{
Image img;
try
{
img = Image.FromStream(conn.Stream);
}
catch( NotAnImageException /* or whatever it is */ )
{
return false;
}
ProcessImage(img);
return true;
}
bool LoadDocument()
{
// etc
}
So you can write
if( !LoadImage() )
LoadDocument();
or extend it to:
if( !LoadImage() && !LoadDocument() )
{
/* Complain */
}
I think empty catch blocks, the way you've coded them, are a very bad idea in general. You're swallowing an exception there. No one will ever know that something is amiss the way you've coded it.
My policy is that if I can't handle and recover from an exception, I should simply allow it to bubble up the call stack to a place where it can be handled. That might mean nothing more than logging the error, but it's better than hiding the error.
If unchecked exceptions are the rule in .NET, I'd recommend that you use just one try/catch block when you must within a single method. I agree - multiple try/catch blocks in a method is ugly and cluttering.
I'm not sure what your code is trying to do. It looks like you're using exceptions as logic: "If an exception isn't thrown, process and return an image; if an exception IS thrown, process and return an HTML document." I think this is a bad design. I'd refactor it into two methods, one each for an image and HTML, and not use exceptions instead of an "if" test.
I like the idea of Eric's example, but I find the implementation ugly: doing work in an if and having a method that does work return a boolean looks very ugly.
My choice would be a method that returns Images, and a similar method
Image LoadImage(HttpConnection conn)
{
try
{
return Image.FromStream(conn.Stream);
}
catch(NotAnImageException)
{
return null;
}
}
and do the work in the original method:
static void DownloadCompleted(HttpConnection conn)
{
Image img = LoadImage(conn);
if(img != null)
{
ProcessImage(img);
return;
}
HtmlDocument doc = LoadDocument(conn);
if(doc != null)
{
ProcessDocument(doc)
return;
}
return;
}
In conjunction to duffymo's answer, if you're dealing with
File input/output, use IOException
Network sockets, use SocketException
XML, use XmlException
That would make catching exceptions tidier as you're not allowing it to bubble up to the generic catch-all exception. It can be slow, if you use the generic catch-all exception as the stack trace will be bubbling up and eating up memory as the references to the Exception's property, InnerException gets nested as a result.
Either way, craft your code to show the exception and log it if necessary or rethrow it to be caught by the catch-all exception...never assume the code will not fail because there's plenty of memory, plenty of disk and so on as that's shooting yourself in the foot.
If you want to design your own Exception class if you are building a unique set of classes and API, inherit from the ApplicationException class.
Edit:
I understand better what the OP is doing...I suggest the following, cleaner implementation, notice how I check the stream to see if there's a HTML tag or a DOC tag as part of XHTML...
static void DownloadCompleted(HttpConnection conn) {
Image img;
HtmlDocument doc;
bool bText = false;
using (System.IO.BinaryReader br = new BinaryReader(conn.Stream)){
char[] chPeek = br.ReadChars(30);
string s = chPeek.ToString().Replace(" ", "");
if (s.IndexOf("<DOC") > 0 || s.IndexOf("<HTML") > 0){
// We have a pure Text!
bText = true;
}
}
if (bText){
doc = new HtmlDocument();
doc.Load(conn.Stream);
}else{
img = Image.FromStream(conn.Stream);
}
}
Increase the length if you so wish depending on how far into the conn.Stream indicating where the html tags are...
Hope this helps,
Best regards,
Tom.
There is no need to try to guess the content type of an HTTP download, which is why you are catching exceptions here. The HTTP protocol defines a Content-Type header field which gives you the MIME type of the downloaded content.
Also, a non-seekable stream can only be read once. To read the content of a stream multiple times, you would have to copy it to a MemoryStream and reset it before each read session with Seek(0, SeekOrigin.Begin).
Answering your exact question: you don't need a catch block at all, try/finally block will work just fine without a catch block.
try
{
int i = 0;
}
finally {}
Often I find myself interacting with files in some way but after writing the code I'm always uncertain how robust it actually is. The problem is that I'm not entirely sure how file related operations can fail and, therefore, the best way to handle exceptions.
The simple solution would seem to be just to catch any IOExceptions thrown by the code and give the user an "Inaccessible file" error message, but is it possible to get a bit more fine-grained error messages? Is there a way to determine the difference between such errors as a file being locked by another program and the data being unreadable due to a hardware error?
Given the following C# code, how would you handle errors in a user friendly (as informative as possible) way?
public class IO
{
public List<string> ReadFile(string path)
{
FileInfo file = new FileInfo(path);
if (!file.Exists)
{
throw new FileNotFoundException();
}
StreamReader reader = file.OpenText();
List<string> text = new List<string>();
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
reader.Close();
reader.Dispose();
return text;
}
public void WriteFile(List<string> text, string path)
{
FileInfo file = new FileInfo(path);
if (!file.Exists)
{
throw new FileNotFoundException();
}
StreamWriter writer = file.CreateText();
foreach(string line in text)
{
writer.WriteLine(line);
}
writer.Flush();
writer.Close();
writer.Dispose();
}
}
...but is it possible to get a bit more fine-grained error messages.
Yes. Go ahead and catch IOException, and use the Exception.ToString() method to get a relatively relevant error message to display. Note that the exceptions generated by the .NET Framework will supply these useful strings, but if you are going to throw your own exception, you must remember to plug in that string into the Exception's constructor, like:
throw new FileNotFoundException("File not found");
Also, absolutely, as per Scott Dorman, use that using statement. The thing to notice, though, is that the using statement doesn't actually catch anything, which is the way it ought to be. Your test to see if the file exists, for instance, will introduce a race condition that may be rather vexing. It doesn't really do you any good to have it in there. So, now, for the reader we have:
try {
using (StreamReader reader = file.OpenText()) {
// Your processing code here
}
} catch (IOException e) {
UI.AlertUserSomehow(e.ToString());
}
In short, for basic file operations:
1. Use using
2, Wrap the using statement or function in a try/catch that catches IOException
3. Use Exception.ToString() in your catch to get a useful error message
4. Don't try to detect exceptional file issues yourself. Let .NET do the throwing for you.
The first thing you should change are your calls to StreamWriter and StreamReader to wrap them in a using statement, like this:
using (StreamReader reader = file.OpenText())
{
List<string> text = new List<string>();
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
}
This will take care of calling Close and Dispose for you and will actually wrap it in a try/finally block so the actual compiled code looks like this:
StreamReader reader = file.OpenText();
try
{
List<string> text = new List<string>();
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
}
finally
{
if (reader != null)
((IDisposable)reader).Dispose();
}
The benefit here is that you ensure the stream gets closed even if an exception occurs.
As far as any more explicit exception handling, it really depends on what you want to happen. In your example you explicitly test if the file exists and throw a FileNotFoundException which may be enough for your users but it may not.
Skip the File.Exists(); either handle it elsewhere or let CreateText()/OpenText() raise it.
The end-user usually only cares if it succeeds or not. If it fails, just say so, he don't want details.
I haven't found a built-in way to get details about what and why something failed in .NET, but if you go native with CreateFile you have thousands of error-codes that can tell you what went wrong.
I don't see the point in checking for existence of a file and throwing a FileNotFoundException with no message. The framework will throw the FileNotFoundException itself, with a message.
Another problem with your example is that you should be using the try/finally pattern or the using statement to ensure your disposable classes are properly disposed even when there is an exception.
I would do this something like the following, catch any exception outside the method, and display the exception's message :
public IList<string> ReadFile(string path)
{
List<string> text = new List<string>();
using(StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
}
return text;
}
I would use the using statement to simplify closing the file. See MSDN the C# using statement
From MSDN:
using (TextWriter w = File.CreateText("log.txt")) {
w.WriteLine("This is line one");
w.WriteLine("This is line two");
}
using (TextReader r = File.OpenText("log.txt")) {
string s;
while ((s = r.ReadLine()) != null) {
Console.WriteLine(s);
}
}
Perhaps this is not what you are looking for, but reconsider the kind you are using exception handling. At first exception handling should not be treated to be "user-friendly", at least as long as you think of a programmer as user.
A sum-up for that may be the following article http://goit-postal.blogspot.com/2007/03/brief-introduction-to-exception.html .