In c#, can I write something like this :
if (
(
try {
...
return true;
}
catch (Exception ex)
{
return false;
}
) == true
)
{
...
}
without having to move all my try/catch block inside a new function
-- edit --
OK. I complete my question. (and maybe answer it a bit).
What is supposed to be in the try/catch is a kind of XmlDocument.TryLoad(stream) (like there's a int.tryParse(string)).
I'll need it only once so that's why I'd wanted to avoid making an extra func.
So my code would be something like
try {
new XmlDocument().Load(foo);
return true;
}
catch (Exception ex)
{
return false;
}
I just want to know if it goes wrong. I don't care the reason (stream empty, bad encoding).
There are a lot of interesting answers but I think what's the more appropriate for me is to create a extension method for xmlDocument. It will be way cleaner (and reusable and easier to read) than trying to force an anonymous method in my statement
You can't use that exact syntax, no. You could write:
Func<bool> func = () =>
{
// Code in here
};
if (func())
{
...
}
... but personally I'd extract it into a separate method. It's likely to be considerably more readable - and potentially easier to test, too.
Not that I'd recommend catching exceptions like this either, but:
public static bool Try(Action action)
{
try
{
action();
return true;
}
catch (Exception)
{
return false;
}
}
Example usages
int x;
int a = 0;
int b = 1;
if (Try(() => x = a/b))
{
}
if (Try(OtherMethod))
{
}
if (Try(OtherMethod(1,2)))
{
}
if (((Func<bool>)(() =>
{
// Multi-statement evaluation
DateTime dt = DateTime.UtcNow;
if (dt.Hour <= 12)
return true;
else
return false;
}))())
{
Console.WriteLine("Early");
}
else
{
Console.WriteLine("Late");
}
From C# Language Specification 5.0 (8.7.1):
The if statement selects a statement for execution based on the value
of a boolean expression.
But your code:
(
try { return true; }
catch (Exception ex) { return false; }
) == true
Is not a boolean expression but a statement.
Related
I like using implicit typing for almost everything because it's clean and simple. However, when I need to wrap a try...catch block around a single statement, I have to break the implicit typing in order to ensure the variable has a defined value. Here's a contrived hypothetical example:
var s = "abc";
// I want to avoid explicit typing here
IQueryable<ABC> result = null;
try {
result = GetData();
} catch (Exception ex) { }
if (result != null)
return result.Single().MyProperty;
else
return 0;
Is there a way I can call GetData() with exception handling, but without having to explicitly define the type of the result variable? Something like GetData().NullOnException()?
This is a common problem. I recommend that you just stick with your existing solution.
If you really want an alternative, here it is:
static T NullOnException<T>(Func<T> producer) where T : class {
try { return producer(); } catch { return null; } //please modify the catch!
}
//now call it
var result = NullOnException(() => GetData());
Please modify this to log the exception or restrict the catch to a concrete type. I do not endorse swallowing all exceptions.
As this answer is being read a lot I want to point out that this implementation is just of demo-quality. In production code you probably should incorporate the suggestions given in the comments. Write yourself a robust, well-designed helper function that will serve you well for years.
Just put your code inside the try:
var s = "abc";
// I want to avoid explicit typing here
try {
var result = GetData();
if (result != null)
return result.Single().MyProperty;
else
return 0;
} catch (Exception ex) { }
I came to a similar solution as #usr, but with slightly different semantics:
T LiftScope<T>(Func<T> ScopedFunction)
{
T result = ScopedFunction();
return result;
}
The purpose of LiftScope is to carry an internal variable out to the caller without compromising implicit typing. This could be used to solve the original problem, except that the try...catch would actually be embedded in the call.
try...catch
var result =
LiftScope(() => {
try { return producer(); } catch { return null; }
});
Now the caller is able to be responsible for exception handling. Furthermore, this can be used generically in a handful of similar use-cases where you have very short-lived scopes.
if
var result =
LiftScope(() => {
if (a == b)
return GetData(true);
else if (b == c)
return GetData(false);
else
return GetData(true, 2);
});
This could also be solved with a ternary-style if statement.
using
var result =
LiftScope(() => {
using (var myContext = new MyDataContext())
{
return myContext.MyTable.Where(w => w.A == B).ToList();
}
});
I am reading a file and information is provided line by line (this I can't change). I want to create an object if the line has x value and if the line has y value, assign some values to the object. this proves to be very challenging. obviously I am doing something wrong.
if (line_split[i].Contains("LabelId"))
{
try
{
gen.m_LabelId_pos.Add(multicast_ports[3], i);
multicast my_multicast = new multicast();
}
catch
{
}
}
else if (line_split[i].Contains("TotalFrameSentCount_PerSecond"))
{
try
{
gen.m_TotalFrameSentCount_PerSecond_pos.Add(multicast_ports[3], i);
// want to assign y value to the object here. but cant
}
catch
{
}
}
You can declare the object outside of the if statement, instantiate it in the if block and set it's value in the else block after you have checked that it isn't null. Something like this:
multicast my_multicast = null;
if (line_split[i].Contains("LabelId"))
{
try
{
gen.m_LabelId_pos.Add(multicast_ports[3], i);
my_multicast = new multicast();
}
catch
{
}
}
else if (line_split[i].Contains("TotalFrameSentCount_PerSecond"))
{
try
{
gen.m_TotalFrameSentCount_PerSecond_pos.Add(multicast_ports[3], i);
if(my_multicast!=null)
{
//do something with my_multicast here
}
}
catch
{
}
}
As an aside note, you should avoid eating your Exceptions, they are meant to help you if something goes wrong, this way catch block will hide them and you won't have a clue what went wrong. Use
catch(Exception err)
{
}
In C# (when using a try / finally) how can I jump to the finally section without calling return.
For example:
public bool SomeMethod()
{
try
{
...
if (...)
{
---> Jump to finally
}
else
{
...
}
...
if (...)
{
---> Jump to finally
}
else
{
...
}
...
return true;
}
finally
{
...
if (...)
return true;
else
return false;
}
}
How can I force a jump to the finally section (without using return)?
Edit:
What I'm trying to do is:
public bool SomeMethod(ref string Error)
{
try
{
bool result = false;
if (...)
---> Exit to Finally
else
...
...
if (...)
---> Exit to Finally
else
...
...
--> more of the above kind of IFs
return true;
}
finally
{
...
if (!result)
{
LogAMessage("");
...
Error = "...";
...
}
return result;
}
}
You could use a label and goto.
However, this seems to suggest that your function is probably not structured well.
In this case, you seem to be using finally as a function - why not extract that logic into a function of its own?
You have a few options:
Add a dummy block either inside or outside your try/finally block and use break:
// dummy block inside
try {
do {
...
if (condition)
break;
...
} while (false);
} finally {
...
}
// dummy block outside
do {
try {
...
if (condition)
break;
...
} finally {
...
}
} while (false);
Add a label in front of the finally block and use goto (note that using goto in general is not recommended).
Put your block into a separate method so that you can use return without leaving the outer method.
You really shouldn't be trying to do this...
Consider re-writing your code in a fashion which means the goto -> finally is not a requirement.
Perhaps pull out the code in the finally block into a method and call it in mulitple places...
Update
You can get the desired behaviour from the following:
public bool SomeMethod(ref string Error)
{
bool result = false;
try
{
if (...)
{
return result;
}
else
{
result = true;
...
return result;
}
}
finally
{
if (!result)
{
LogAMessage("");
...
Error = "...";
...
}
}
However, to achieve such a thing you should check out the Delegation Pattern for a far cleaner way of achieving this logging.
Maybe consider placing this method in a class which implements IDisposable.
Then you could invoke this method whilst it is wrapped a using statement and will be guaranteed to be cleared up.
I have a method that calls a SQLServer function to perform a free text search against a table. That function will occasionally on the first call result in a SQLException: "Word breaking timed out for the full-text query string". So typically I want to retry that request because it will succeed on subsequent requests. What is good style for structuring the retry logic. At the moment I have the following:
var retryCount = 0;
var results = new List<UserSummaryDto>();
using (var ctx = new UsersDataContext(ConfigurationManager.ConnectionStrings[CONNECTION_STRING_KEY].ConnectionString))
{
for (; ; )
{
try
{
results = ctx.SearchPhoneList(value, maxRows)
.Select(user => user.ToDto())
.ToList();
break;
}
catch (SqlException)
{
retryCount++;
if (retryCount > MAX_RETRY) throw;
}
}
}
return results;
I'd change the exception handling to only retry on certain errors:
1204, 1205 deadlocks
-2 timeout
-1 connection broken
These are the basic "retryable" errors
catch (SqlException ex)
{
if !(ex.Number == 1205 || ex.Number == 1204 || ... )
{
throw
}
retryCount++;
if (retryCount > MAX_RETRY) throw;
}
Edit, I clean forgot about waits so you don't hammer the SQL box:
Add a 500 ms wait on deadlock
Add a 5 sec delay on timeout
Edit 2:
I'm a Developer DBA, don't do much C#.
My answer was to correct exception processing for the calls...
Thanks for all the feedback. I'm answering this myself so I can incorporate elements from the answers given. Please let me know if I've missed something. My method becomes:
var results = new List<UserSummaryDto>();
Retry<UsersDataContext>(ctx => results = ctx.SearchPhoneList(value, maxRows)
.Select(user => user.ToDto())
.ToList());
return results;
And I've refactored the original method for reuse. Still lots of levels of nesting. It also relies on there being a default constructor for the data context which may be too restrictive. #Martin, I considered including your PreserveStackTrace method but in this case I don't think it really adds enough value - good to know for future reference thanks:
private const int MAX_RETRY = 2;
private const double LONG_WAIT_SECONDS = 5;
private const double SHORT_WAIT_SECONDS = 0.5;
private static readonly TimeSpan longWait = TimeSpan.FromSeconds(LONG_WAIT_SECONDS);
private static readonly TimeSpan shortWait = TimeSpan.FromSeconds(SHORT_WAIT_SECONDS);
private enum RetryableSqlErrors
{
Timeout = -2,
NoLock = 1204,
Deadlock = 1205,
WordbreakerTimeout = 30053,
}
private void Retry<T>(Action<T> retryAction) where T : DataContext, new()
{
var retryCount = 0;
using (var ctx = new T())
{
for (;;)
{
try
{
retryAction(ctx);
break;
}
catch (SqlException ex)
when (ex.Number == (int) RetryableSqlErrors.Timeout &&
retryCount < MAX_RETRY)
{
Thread.Sleep(longWait);
}
catch (SqlException ex)
when (Enum.IsDefined(typeof(RetryableSqlErrors), ex.Number) &&
retryCount < MAX_RETRY)
{
Thread.Sleep(shortWait);
}
retryCount++;
}
}
}
My enum of retryables for sql looks like this:
SqlConnectionBroken = -1,
SqlTimeout = -2,
SqlOutOfMemory = 701,
SqlOutOfLocks = 1204,
SqlDeadlockVictim = 1205,
SqlLockRequestTimeout = 1222,
SqlTimeoutWaitingForMemoryResource = 8645,
SqlLowMemoryCondition = 8651,
SqlWordbreakerTimeout = 30053
It's not good style, but sometimes you have to do it, because you simply can't change existing code and have to deal with it.
I am using the following generic method for this scenario. Note the PreserveStackTrace() method, which can sometimes be very helpful in a re-throw scenario.
public static void RetryBeforeThrow<T>(Action action, int retries, int timeout) where T : Exception
{
if (action == null)
throw new ArgumentNullException("action", string.Format("Argument '{0}' cannot be null.", "action"));
int tries = 1;
do
{
try
{
action();
return;
}
catch (T ex)
{
if (retries <= 0)
{
PreserveStackTrace(ex);
throw;
}
Thread.Sleep(timeout);
}
}
while (tries++ < retries);
}
/// <summary>
/// Sets a flag on an <see cref="T:System.Exception"/> so that all the stack trace information is preserved
/// when the exception is re-thrown.
/// </summary>
/// <remarks>This is useful because "throw" removes information, such as the original stack frame.</remarks>
/// <see href="http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx"/>
public static void PreserveStackTrace(Exception ex)
{
MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic);
preserveStackTrace.Invoke(ex, null);
}
You would call it like that:
RetryBeforeThrow<SqlException>(() => MethodWhichFails(), 3, 100);
There is no good style for doing something like this. You'd be better off figuring out why the request fails the first time but succeeds the second time.
It seems possible that Sql Server has to initially compile an execution plan and then execute the query. So the first call fails because the combined times exceed your timeout property, and succeeds the second time because the execution plan is already compiled and saved.
I don't know how UsersDataContext works, but it may be the case that you have the option to Prepare the query before actually executing it.
Real Answer: If I had to do this, I would retry just once and not again, like this:
var results = new List<UserSummaryDto>();
using (var ctx = new
UsersDataContext(ConfigurationManager.ConnectionStrings[CONNECTION_STRING_KEY].ConnectionString))
{
try
{
results = ctx.SearchPhoneList(value, maxRows)
.Select(user => user.ToDto())
.ToList();
break;
}
catch (SqlException)
{
try
{
results = ctx.SearchPhoneList(value, maxRows)
.Select(user => user.ToDto())
.ToList();
break;
}
catch (SqlException)
{
// set return value, or indicate failure to user however
}
}
}
}
return results;
While I might trust you to not abuse the retry process, you'd be tempting your successor to increase the retry count as a quick fix.
I think annotating a method with an aspect specifying the retry count would result in more structured code, although it needs some infrastructure coding.
You can simply use SqlConnectionStringBuilder properties to sql connection retry.
var conBuilder = new SqlConnectionStringBuilder("Server=.;Database=xxxx;Trusted_Connection=True;MultipleActiveResultSets=true");
conBuilder.ConnectTimeout = 90;
conBuilder.ConnectRetryInterval = 15;
conBuilder.ConnectRetryCount = 6;
Note:- Required .Net 4.5 or later.
Pull the relevant code out into its own method, then use recursion.
Pseudo-code:
try
{
doDatabaseCall();
}
catch (exception e)
{
//Check exception object to confirm its the error you've been experiencing as opposed to the server being offline.
doDatabaseCall();
}
In Delphi I could do something like this:
try
if not DoSomething then
Exit;
if not DoSomething2 then
Exit;
if not DoSomething3 then
Exit;
finally
DoSomethingElse;
end;
In other means if method DoSomething results false then the program flow is transffered to the finally block and DoSomething2 and DoSomething3 are not executed.
How to achieve such behaviour in C#?
Thanks in advance.
Edit1:
The below example doesn't compile in VS 2008
Edit2: I am sorry I was to fast and forget the return statement;
XElement OrderStatus(q_order_status Request)
{
XElement Response;
try
{
if (DoSomething() != 0 )
{
return;
}
}
catch(Exception e)
{
// catch some errors and eventually pass the e.Message to the Response
}
finally
{
Response = new XElement("SomeTag", "SomeResponse");
}
return Response;
}
Edit3:
After testing it seems that the easiest way to achieve this is to throw an exception if the result of DoSomething1 is false. I can throw my own execption, write a specific message and pass it to the finally clause.
You really shouldn't be using exception handling constructs for flow control. That said, Exit is comparable to return in C#. As the MSDN Documentation about the [return keyword][1] says:
If the return statement is inside a try block, the finally block, if one exists, will be executed before control returns to the calling method.
In general a finally-block will almost always execute if the corresponding try-block has been reached. There are a few rare situations where it is impossible to guarantee that the finally-block executes, but they are all fatal errors, upon which programs should likely immediately crash.
How your code would look in C#:
try
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
finally
{
DoSomethingElse();
}
But again, don't do this. try and finally are intended for handling exceptions, not for normal flow control.
Reply to your edit:
In your code return doesn't compile because the return type of the method is XElement and return by itself can only be used when the return type is void. You could use return new XElement("SomeTag", "SomeResponse");, as that is what the finally would be doing anyway, or you could assign Response earlier and do return Response;.
Note though that while the finally always executes, the return Response; that comes after it doesn't execute if the reason went into the finally-block is because you did a return inside the try-block.
Answer to updated question:
The reason you're having trouble doing this in an elegant way, is because you seem to be using a combination of return values and exceptions. You should consider manually raising an exception instead of using return values if the sitation is, well, exceptional.
Assuming there is a good reason for the return values however, I'm thinking it might be clearer to go without a finally block altogether, and to include a return at the end of the try block and also in your catch block. That would save you from passing the exception message in a messy way.
I can't really say what the best solution would be, since your code snippet does not show what Response would be if DoSomething() returns a non-zero value.
Original answer:
It depends a little on what you're trying to accomplish. Are exceptions actually being thrown in any of the methods? Otherwise there is no good reason to use a try-finally pattern. This would be equivalent (though maybe not advisable for readability):
bool doneEverything = DoSomething() && DoSomething2() && DoSomething3();
DoSomethingElse();
If there are exceptions being thrown, and handled at a higher level, I'd recommend isolating this code in a separate method, so you can use a return statement*.
void DoStuff()
{
try
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
finally
{
DoSomethingElse();
}
}
To answer your question about when the finally code block is executed: it is always executed, unless the executing thread terminates prematurely.
*: Some restructuring is recommended, because there is no equivalent of the Delphi Exit. The break statement comes closest, but it can only be used in loop constructs or switch blocks. To mimic Exit behavior, you would need goto and a label. We wouldn't want that, now would we? :)
Why not make the three try-lines a common if/else block? Instead of exit, call the DoSomethingElse. Like so:
if (DoSomething() == false)
{
DoSomethingElse();
}
else if (DoSomething2() == false)
{
DoSomethingElse();
}
else if (DoSomething3() == false)
{
DoSomethingElse();
}
I would like to say that "C# is not Delphi", but that would be a bit arrogant.
In C#, finally is executed as well when return is called inside the try statement.
bool doSomething = false;
bool doSomething2 = true;
try
{
if( !doSomething )
{
Console.WriteLine ("not dosomething");
return;
}
if( !doSomething2 )
{
Console.WriteLine ("not dosomething 2");
return;
}
}
finally
{
Console.WriteLine ("In finally");
}
What about switch case of course If you don't mean the finally in c# by saying finally block. default case is the finally block then and you can also find flow control example and here at msdn : Flow Control (C# vs. Java)
static void Main(string[] args)
{
switch (args[0])
{
case "copy":
//...
break;
case "move":
//...
goto case "delete";
case "del":
case "remove":
case "delete":
//...
break;
default:
//...
break;
}
}
In this sort of situation, understanding the question as dealing exclusively with the non-exception handling case, I would refactor the contents of the try into a private helper method, like this
void BranchOnContext()
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
// last one will drop out and return anyway
DoSomething3();
}
void DoStuff()
{
BranchOnContext(); // Assumed not to throw
DoSomethingElse(); // Always the next thing to be executed
}
EDIT -- tracking the changed requirement
void DoStuff()
{
string message = string.Empty;
try {
BranchOnContext();
} catch (MyExpectedException me) { // only catch exceptions I'm prepared to handle
message = me.Message;
}
DoSomethingElse(message); // Always the next thing to be executed
}
Taking another crack at this with the updated info:
I want DoSomethingElse to be executed
always and I want it to include
message from possible exception
If any of the DoSomething's return 0, null is returned. If not, the generic message is created. If there was an exception, it is caught and a message with its info is returned. How about this?
XElement OrderStatus(q_order_status Request)
{
try
{
if (DoSomething() != 0 )
{
return null;
}
else
{
return new XElement("SomeTag", "SomeResponse");
}
}
catch(Exception e)
{
// catch some errors and eventually pass the e.Message to the Response
return new XElement(e.tag, e.response);
}
}
Im still struggling with how to, in a good way, put finally into this.
I find it quite similar in behavior to the Delphi's one which I have shown on the beginning. I am interested in your comments. Response is dependent on the DoSomethings result.
XElement OrderStatus(q_order_status Request)
{
XElement Response;
int result = 0;
string Message = "";
try
{
result = DoSomething1();
if (result != 0)
{
throw new DoSomethingException("DoSomething1 has failed!");
}
result = DoSomething2();
if (result != 0)
{
throw new DoSomethingException("DoSomething2 has failed!");
}
result = DoSomething3();
if (result != 0)
{
throw new DoSomethingException("DoSomething3 has failed!");
}
Message = "All tests has been passed.";
}
catch(DoSomethingException e)
{
Message = e.Message;
}
catch(Exception e)
{
Message = e.Message;
}
finally
{
Response = new XElement("SomeTag", Message);
}
return Response;
}
What do you think?
void funcA()
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
void funcB()
{
funcA();
DoSomethingElse;
}
This appears to replicate the delphi:-
try
{
if(DoSomething())
if(DoSomething2())
DoSomething3();
}
finally
{
DoSomethingElse();
}
an alternate style (some people will hate this style, others will love it.):-
try
{
DoSomething() && DoSomething2() && DoSomething3();
}
finally
{
DoSomethingElse();
}
I get the impression you want some other behaviour though?
Goto version?
try
{
if (!DoSomething())
goto Exit;
if (!DoSomething2())
goto Exit;
if (!DoSomething3())
goto Exit;
Exit:;
}
finally
{
DoSomethingElse();
}
Note the irritating ; after the label, it seems a label must precede a statement.
Just had an epiphany:-
Func<bool>[] somethings = new Func<bool>[] {DoSomething, DoSomething2, DoSomething3};
try
{
foreach (Func<bool> something in somethings)
{
if (!something())
break;
}
}
finally
{
DoSomethingElse();
}