Combine { using } statement and {try-catch} statement in C#

What would be the best way to combine  {try-catch} statement and { using } statement?

Just put { using } statement in try section??

    try 
    {
       // Put using statement here
       
    }
    catch (Exception ex) 
    {
       // handle exception
    }

Open in new window


The below code (I got it from http://www.aspsnippets.com/Articles/Export-data-from-SQL-Server-to-Text-file-in-C-and-VBNet.aspx)  does Not handle Exceptions. What would be the best way to fix it??

Put block { using (SqlConnection con = new SqlConnection(constr)) }  in try section??

    string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand("SELECT * FROM Customers"))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.Connection = con;
                sda.SelectCommand = cmd;
                using (DataTable dt = new DataTable())
                {
                    sda.Fill(dt);
 
                    //Build the Text file data.
                    string txt = string.Empty;
 
                    foreach (DataColumn column in dt.Columns)
                    {
                        //Add the Header row for Text file.
                        txt += column.ColumnName + "\t\t";
                    }
 
                    //Add new line.
                    txt += "\r\n";
 
                    foreach (DataRow row in dt.Rows)
                    {
                        foreach (DataColumn column in dt.Columns)
                        {
                            //Add the Data rows.
                            txt += row[column.ColumnName].ToString() + "\t\t";
                        }
 
                        //Add new line.
                        txt += "\r\n";
                    }
                }
            }
        }
    }

Open in new window


Thanks
niceguy971Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
>>Just put { using } statement in try section??

Yes and then again no.
The using will dispose of the object when the using block is left.  So should an exception be thrown then do you need the object created in the using statement in the catch.  Yes - using outside of try, no - using inside of try is OK.


>>What would be the best way to fix it??
Probably to put it all inside a try block.  See the first part of my comment.
raman kannanCommented:
Yes. I would suggest to go with the first option.

Enclosing your Using statement with {try-catch} statement sounds good.
Karrtik IyerSoftware ArchitectCommented:
There are two options as you might have also identified. I have shown both of them below.
I prefer the option 2 which is try/catch outside the using statement, this has served us well. The reasons are:
1> Normally in my experience and our scenarios catch statement used to take an action of unknown duration, like display of  message to the user.
2> We wanted to dispose of our resources before doing that.
In these scenarios for us the try-catch block is usually in a different method further up the call stack from the using. It is not usual for a method to know how to handle exceptions that occur within it like below.
private void LoadAction()
{
    try
    {
        LoadFile(myFile); // The using statement will appear somewhere in here.
    }
    catch (IOException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Open in new window

3. Also if try and catch is within the using statement, the other problem could be that even last "}" (curly brace) of using block can thrown exceptions as explained in this MSDN article.Last curly brace issue

But then are reasons when we may want to use option 1 (try catch inside using statement) as well, such cases are:
1> Catch statement needs to access the variable declared in a using statement.
2> Catch statement needs the object referenced in the using block before it being disposed.


option 1:
using (var myObject = new MyClass())
{
   try
   {
      // something here...
   }
   catch(Exception ex)
   {
      // Handle exception
   }
}

Open in new window

Option 2:
try
{
   using (var myObject = new MyClass())
   {
      // something here...
   }
}
catch(Exception ex)
{
   // Handle exception
}

Open in new window

Why Diversity in Tech Matters

Kesha Williams, certified professional and software developer, explores the imbalance of diversity in the world of technology -- especially when it comes to hiring women. She showcases ways she's making a difference through the Colors of STEM program.

PawełI Design & Develop SoftwareCommented:
an alternative approach you can use; is to have a finally block to dispose your connection

var con = new SqlConnection(constr);

try{
  //stuff with your connection
}
catch(Exception ex){
  //handle exceptions
}
finally{
  con.Dispose();
}

the finally block will always fire regardless if there's an exception, that being said i'd probably still wrap the using inside the try, but it's your call.

Open in new window

it_saigeDeveloperCommented:
Since a using statement is really nothing more than a try...finally block of code; e.g. -
using (var command = new SqlCommand("SELECT * FROM Customers"))
{
	// Do something with our command
}

// When compiled becomes
SqlCommand command;
try
{
	command = new SqlCommand("SELECT * FROM Customers");
}
finally
{
	if (command != null)
	{
		command.Dispose()
	}
}

Open in new window

You can enclose your using statement in a try...catch without much worry with regards to exception bubbling (as alluded to by Andy).

What is meant by this is that any exception thrown from a using statement would act the same as any exception thrown from any method, it bubbles up the stack until it reaches the most internal implementation of catch that matches it's exception signature.

What do I mean by this?  Consider the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace EE_Q28909760
{
	class Program
	{
		static void Main(string[] args)
		{
			try
			{
				try
				{
					try
					{
						using (Branch branch = new Branch())
						{
							branch.Add(null);
						}
						throw new ArgumentException();
					}
					catch (RootException ex)
					{
						Console.WriteLine(ex);
					}
				}
				catch (BranchException ex)
				{
					Console.WriteLine(ex);
				}
			}
			finally
			{
				Console.WriteLine("Application will close now.");
				Console.ReadLine();
			}
		}
	}

	class Branch : List<Leaf>, IDisposable
	{
		public Branch() { ;}
		public Branch(int capacity) : base(capacity) { ;}
		public Branch(IEnumerable<Leaf> collection) : base(collection) { ;}

		public void Add(Leaf item)
		{
			if (item == null)
				throw new BranchException("Cannot add null leaf", new LeafException("invalid leaf", new ArgumentNullException()));
			base.Add(item);
		}

		public void Dispose()
		{
			for (int i = Count - 1; i > 0; i--)
				this[i].Dispose();
		}
	}

	class Leaf : IDisposable
	{
		private string _name;
		public string Name
		{
			get { return _name; }
			set 
			{
				if (value == null)
					throw new LeafException("Leaf name cannot be null", new ArgumentNullException());

				if (string.IsNullOrWhiteSpace(value))
					throw new LeafException("Leaf cannot be unnamed", new ArgumentException());

				_name = value; 
			}
		}

		public Leaf(string name)
		{
			if (name == null)
				throw new LeafException("Leaf name cannot be null", new ArgumentNullException());

			if (string.IsNullOrWhiteSpace(name))
				throw new LeafException("Leaf cannot be unnamed", new ArgumentException());

			Name = name;
		}

		public void Dispose()
		{
			Name = string.Empty;
		}
	}

	class RootException : Exception
	{
		public RootException() { ;}
		public RootException(string message) : base(message) { ;}
		public RootException(string message, BranchException branch) : base(message, branch) { ;}
		public RootException(SerializationInfo info, StreamingContext context) : base(info, context) { ;}
	}

	class BranchException : Exception
	{
		public BranchException() { ;}
		public BranchException(string message) : base(message) { ;}
		public BranchException(string message, LeafException leaf) : base(message, leaf) { ;}
		public BranchException(SerializationInfo info, StreamingContext context) : base(info, context) { ;}
	}

	class LeafException : Exception
	{
		public LeafException() { ;}
		public LeafException(string message) : base(message) { ;}
		public LeafException(string message, Exception ex) : base(message, ex) { ;}
		public LeafException(SerializationInfo info, StreamingContext context) : base(info, context) { ;}
	}
}

Open in new window

When I run this, the exception caused by creating a null leaf gets caught by the middle try block as it is the most internal try block that catches the BranchException signature (the most inner try...catch, catches a RootException); e.g. -Capture.JPGNow if I create a real leaf that follows the rules, I have no catches that will catch an ArgumentException, so what happens next is based upon the WER (Windows Error Reporting) configuration; e.g. -This is what happens on my system when an unhandled exception is encountered.Or if I try to create an invalid leaf, again no try...catch blocks catch a LeafException, so I should expect similar WER results as those for forcing an ArgumentException -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace EE_Q28909760
{
	class Program
	{
		static void Main(string[] args)
		{
			try
			{
				try
				{
					try
					{
						using (Branch branch = new Branch())
						{
							branch.Add(new Leaf(""));
						}
					}
					catch (RootException ex)
					{
						Console.WriteLine(ex);
					}
				}
				catch (BranchException ex)
				{
					Console.WriteLine(ex);
				}
			}
			finally
			{
				Console.WriteLine("Application will close now.");
				Console.ReadLine();
			}
		}
	}

	class Branch : List<Leaf>, IDisposable
	{
		public Branch() { ;}
		public Branch(int capacity) : base(capacity) { ;}
		public Branch(IEnumerable<Leaf> collection) : base(collection) { ;}

		public void Add(Leaf item)
		{
			if (item == null)
				throw new BranchException("Cannot add null leaf", new LeafException("invalid leaf", new ArgumentNullException()));
			base.Add(item);
		}

		public void Dispose()
		{
			for (int i = Count - 1; i > 0; i--)
				this[i].Dispose();
		}
	}

	class Leaf : IDisposable
	{
		private string _name;
		public string Name
		{
			get { return _name; }
			set 
			{
				if (value == null)
					throw new LeafException("Leaf name cannot be null", new ArgumentNullException());

				if (string.IsNullOrWhiteSpace(value))
					throw new LeafException("Leaf cannot be unnamed", new ArgumentException());

				_name = value; 
			}
		}

		public Leaf(string name)
		{
			if (name == null)
				throw new LeafException("Leaf name cannot be null", new ArgumentNullException());

			if (string.IsNullOrWhiteSpace(name))
				throw new LeafException("Leaf cannot be unnamed", new ArgumentException());

			Name = name;
		}

		public void Dispose()
		{
			Name = string.Empty;
		}
	}

	class RootException : Exception
	{
		public RootException() { ;}
		public RootException(string message) : base(message) { ;}
		public RootException(string message, BranchException branch) : base(message, branch) { ;}
		public RootException(SerializationInfo info, StreamingContext context) : base(info, context) { ;}
	}

	class BranchException : Exception
	{
		public BranchException() { ;}
		public BranchException(string message) : base(message) { ;}
		public BranchException(string message, LeafException leaf) : base(message, leaf) { ;}
		public BranchException(SerializationInfo info, StreamingContext context) : base(info, context) { ;}
	}

	class LeafException : Exception
	{
		public LeafException() { ;}
		public LeafException(string message) : base(message) { ;}
		public LeafException(string message, Exception ex) : base(message, ex) { ;}
		public LeafException(SerializationInfo info, StreamingContext context) : base(info, context) { ;}
	}
}

Open in new window

Which results in -Capture.JPG-saige-

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
niceguy971Author Commented:
Thanks!
niceguy971Author Commented:
Thanks!!
niceguy971Author Commented:
Thanks
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.