Can exceptions be caught inside a using block, and if so what is the syntax?
So, something like the following:
using (var creatingThing = new MyCreatingThing())
{
creatingThing.CreateSomething();
catch()
{
creatingThing.Rollback();
}
}
Can this be done? Or do I need to write this code manually (ie without a using)?
You can put a try/catch inside the using statement, or outside:
using (...)
{
try
{
...
}
catch
{
...
}
}
Or...
try
{
using (...)
{
...
}
}
catch
{
...
}
However, you can't just put a catch block without a try block.
Choose the right one based on what whether you need to catch exceptions which are thrown by the resource acquisition expression, whether you want the resource to be disposed before your catch block is executed, and whether you need access to the resource variable within the catch block.
You cannot implicitly enlist in the try...finally block that the compiler generates (for the using statement). You have to add another try statement, which will be nested within the generated block:
using (var creatingThing = new MyCreatingThing())
{
try
{
creatingThing.CreateSomething();
}
catch
{
creatingThing.Rollback();
}
}
Note, the a using is really a try/finally under the covers, so it may be easier the code it that way:
MyCreatingThing creatingThing = null;
try
{
creatingThing = new MyNCreatingThing())
creatingThing.CreateSomething();
}
catch()
{
Console.WriteLine("An Exception happened");
if (creatingThing !=null)
creatingThing.Rollback();
}
finally
{
if (creatingThing !=null)
creatingThing.Dispose();
}
Sure, just add the try inside the using:
using (var creatingThing = new MyCreatingThing())
{
try
{
creatingThing.CreateSomething();
}
catch(Exception ex)
{
creatingThing.Rollback();
}
}
Related
My code is currently
using(var driver = new driver()){something}
And I want to be able to catch exceptions. However I only want to catch exceptions thrown by "driver = new driver". Looking online I can find how to catch exceptions thrown by the whole thing or by "something" but I cannot work out how to put a try-catch into the "using" parameter.
It's a very strange requirement, but whatever that's your call.
You should get rid of the using completely, and handle the dispose yourself (which has the same result).
This is what you want:
driver driver = null;
try
{
try
{
driver = new driver();
}
catch(Exception ex)
{
// Here is your specific exception.
}
// Do something
}
finally
{
if(driver != null)
driver.Dispose();
}
Just do it:
Driver driver = null;
try
{
driver = new Driver();
}
catch()
{
// do whatever, throw, fail, return...
}
// if you did not break out of your logic in the catch (why not?)
// add an if(driver != null) before you proceed
using(driver)
{
// something
}
You can add a method to construct your driver and put your try/catch in there:
private static Driver CreateDriver()
{
try
{
return new Driver();
}
catch(Exception ex)
{
// whatever other exception handling you want
return null;
}
}
using(var driver = CreateDriver())
{
// something
}
Of course, if you do this, when your something code is executing inside the using block, driver may be null, so you'll need to check for this, e.g.:
using(var driver = CreateDriver())
{
if (driver != null)
{
// something
}
}
The "using" clause, primarily function is to dispose managed code resources once the process inside the clause has been completed. It "hides" a try catch block inside it, but if you really want to handle errors, you need to do it yourself.
eg.
Try
{
//do stuff
}
catch (exception ex)
{
//handle exception
//resource.Dispose();
}
After you handle your exceptions, you should dispose the unused resources by calling .Dispose(), assuming that the latter is a managed code resource and encapsulates the IDisposable interface
I am intrested if i use using (that close all connection) inside try catch
try{
using (var browser = new IE("https://www.bbvanetcash.com/local_kyop/KYOPSolicitarCredenciales.html"))
{
clsUtils.WriteToLog("Trying to login", true, true);
browser.Visible = false;
browser.TextField(Find.ByName("cod_emp")).Value = _company;
browser.TextField(Find.ByName("cod_usu")).Value = _strUser;
browser.TextField(Find.ByName("eai_password")).Value = _strPass;
browser.Button(Find.ByClass("grandote estirado azul")).Click();
browser.WaitForComplete();
clsUtils.WriteToLog("Logged ", true, true);
connected = true;
var cookie = browser.Eval("document.cookie");
CookieContainer Cc = GetCc(cookie);
} catch (Exception ex)
{
Console.WriteLine("(TryToLogin)-->Catching the {0} exception .", ex.GetType());
return connected;
}
}
and if one of steps gona fail the using gonna close the connection or it just gona go to catch?
MSDN:
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 Disposein a finally block; in fact, this is how the using statement is translated by the compiler.
yes it does, if you are using a using statement i has to implement the Idispose class.
so if you are using something like below
using (foo)
{
//...
}
the compiler will interpret like below.
try
{
//...
}
finally
{
foo.Dispose();
}
hope this helps.
As I know that Using statement has built in implementation of Dispose() and Try-Catch. So I want to know few things
Is it possible to log an exception inside using statement without
using try-catch block , either inside or outside the statement. If
not, then why its built in to the statement.
Nested or overuse of try-catch is not preferred, then why such model
preferred to use.
using (some_resource)
{
try
{
}
catch
{
}
finally
{
//my exception logging mechanism
}
}
will become
try
{
try
{
}
catch
{
}
finally
{
//my exception logging mechanism
}
}
catch
{
}
finally
{
//some_resource.Dispose()
}
A using statement involves try/finally; there is no catch. But frankly, your concern is overkill; multiply-nested and complex try/catch/finally is "undesirable" because:
it makes the code hard to read
and even harder to get right (most people get it wrong, alas)
it is frequently misused
it suggests your method is doing too much
With using, this isn't an issue; it makes the intent very clean, without adding complexity or concern.
I would just use:
using (some_resource) {
try {
// some code
} catch (Exception ex) {
LogIt(ex);
throw;
}
}
Using compiles to Try{}Finally{}. See the following question: Does a C# using statement perform try/finally?
The reason for this is so that the resource will be disposed of regardless of if an exception is thrown. Resource disposal is the purpose of the using statement.
The correct implementation is:
using(Resource myresource = GetResource())
{
try
{}
catch(Exception e)
{ //Maybe log the exception here when it happens?
}
}
I know how to use try/catch block in case of database calls and know how to use "using" directive in context of using try/finally construction as well.
But, can I mix them? I mean when I use "using" directive can I use try/catch construction as well because I still need to handle possible errors?
You can definitely use both together.
A using block is basically just a bit of syntactic sugar for a try/finally block and you can nest try/finally blocks if you wish.
using (var foo = ...)
{
// ...
}
Is roughly equivalent to this:
var foo = ...;
try
{
// ...
}
finally
{
foo.Dispose();
}
Of course you can do it:
using (var con = new SomeConnection()) {
try {
// do some stuff
}
catch (SomeException ex) {
// error handling
}
}
using is translated by the compiler into a try..finally, so it's not very different from nesting a try..catch inside a try..finally.
This one is perfectly valid:
using (var stream = new MemoryStream())
{
try
{
// Do something with the memory stream
}
catch(Exception ex)
{
// Do something to handle the exception
}
}
The compiler would translate this into
var stream = new MemoryStream();
try
{
try
{
// Do something with the memory stream
}
catch(Exception ex)
{
// Do something to handle the exception
}
}
finally
{
if (stream != null)
{
stream.Dispose();
}
}
Of course this nesting works the other way round as well (as in nesting a using-block within a try...catch-block.
A using such as:
using (var connection = new SqlConnection())
{
connection.Open
// do some stuff with the connection
}
is just a syntactic shortcut for coding something like the following.
SqlConnection connection = null;
try
{
connection = new SqlConnection();
connection.Open
// do some stuff with the connection
}
finally
{
if (connection != null)
{
connection.Dispose()
}
}
This means, yes, you can mix it with other try..catch, or whatever. It would just be like nesting a try..catch in a try..finally.
It is only there as a shortcut to make sure the item you are "using" is disposed of when it goes out of scope. It places no real limitation on what you do inside the scope, including providing your own try..catch exception handling.
How to correctly let an exception to bubble up?
If I use Try-Catch when calling a method, is just throwing an exception inside a method like not trying to catch it at all?
For illustration: Are these approaches do the same work?
Example 1:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
...
}
Example 2:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
try
{
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
}
catch (Exception)
{
throw;
}
...
}
Yes, those 2 approaches have almost the same effect; rethrowing will unwind the stack of the exception - meaning the stack frames "below" the method where the throw; will be discarded. They'll still be in the stack trace, but you won't be able to access their local variables in the debugger unless you break on thrown exceptions.
A catch/throw block like the one below where you don't do anything with the exception (like logging), is useless:
catch (Exception)
{
throw;
}
Remove it to clean up, in both your samples. In general, avoid entering a catch block if possible
And your method has another exception related problem, it does not free resources properly. The tr2.Close(); belongs in a finally clause but it's much easier to let the compiler handle that with a using() {} block :
void MyFileHandlingMethod()
{
...
using (TextReader tr2 = new StreamReader(nfilepath))
{
resultN = tr2.ReadLine();
} //tr2.Dispose() inserted automatically here
...
}
First of all you should use the using block with resources as this will take care of closing your resources correctly. The second example is pretty much useless as you don't do any work in the exception handler. Either you should remove it, or wrap it in another Exception to add some information.
Yes, the result is the same.
However, both will result in an unclosed stream if there is an error while reading it. You should use a using block or a try ... finally to make sure that the stream is closed:
using (TextReader tr2 = new StreamReader(nfilepath)) {
resultN = tr2.ReadLine();
}
Note that there is no Close in this code. The using block will dispose the StreamReader, which will close the stream.
The using block is compiled into a try ... finally which it uses to make sure that the StreamReader is always disposed, but the exception will bubble up to the calling method.
I suggest you use your first example, with these changes:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...";
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
throw; // rethrow the same exception.
}
// no need for second catch}
You probably want to rethrow the exception once you have logged it, because you are not doing any actual recovery from the error.