Working on a project where a sequential set of methods must be run every x seconds. Right now I have the methods contained within another "parent method", and just sequentially call them right after another.
class DoTheseThings()
{
DoThis();
NowDoThat();
NowDoThis();
MoreWork();
AndImSpent();
}
Each method must run successfully without throwing an exception before the next step can be done. So now I wrapped each of those methods with a while and try..catch, then in the catch execute that method again.
while( !hadError )
{
try
{
DoThis();
}
catch(Exception doThisException )
{
hadError = true;
}
}
This seems smelly and not very dry. Is there a better way to do this so I'm not wrapping any new functionality in the same methods. Isn't some kind of Delegate collection the proper way to implement this?
Is there a more "proper" solution?
Action[] work=new Action[]{new Action(DoThis), new Action(NowDoThat),
new Action(NowDoThis), new Action(MoreWork), new Action(AndImSpent)};
int current =0;
while(current!=work.Length)
{
try
{
work[current]();
current++;
}
catch(Exception ex)
{
// log the error or whatever
// maybe sleep a while to not kill the processors if a successful execution depends on time elapsed
}
}
Isn't some kind of Delegate collection the proper way to implement this?
Delegate is a possible way to solve this problem.
Just create a delegate something like:
public delegate void WorkDelegate();
and put them in arraylist which you can iterate over.
I have a personal religious belief that you shouldn't catch System.Exception, or more accurately, you should only catch the exceptions you know how to handle.
That being said, I am going to assume that each one of the methods that you are calling are doing something different, and could result in different exceptions being thrown. Which means you would likely need to have different handlers for each method.
If you follow my religion as well, and the second statement is true, then you are not repeating code unnecessarily. Unless you have other requirements, my recommendations to improve your code would be:
1) Put the try-catch in each method, not around each method call.
2) Have the catches within each method catch ONLY the exceptions you know about.
http://blogs.msdn.com/fxcop/archive/2006/06/14/631923.aspx
http://blogs.msdn.com/oldnewthing/archive/2005/01/14/352949.aspx
http://www.joelonsoftware.com/articles/Wrong.html
HTH ...
your example seems ok.. its a dry one but will do the job well!! actually if this methods execute db access.. you can use transaction to ensure integrity...
if your dealing with shared variables for multi threader programs.. it is cleaner to use synchronization.. the most important thing in coding is that you write the proper code... that has less bugs.. and will do the task correctly..
public void DoTheseThings()
{
SafelyDoEach( new Action[]{
DoThis,
NowDoThat,
NowDoThis,
MoreWork,
AndImSpent
})
}
public void SafelyDoEach( params Action[] actions )
{
try
{
foreach( var a in actions )
a();
}
catch( Exception doThisException )
{
// blindly swallowing every exception like this is a terrible idea
// you should really only be swallowing a specific MyAbortedException type
return;
}
}
What would be the reason that an error was occuring?
If this were a resource issue, such as access to something like a connection or object, then you might want to look at using monitors, semaphores, or just locking.
lock (resource)
{
Dosomething(resource);
}
This way if a previous method is accessing the resource, then you can wait until it releases the resource to continue.
Ideally, you shouldn't have to run a loop to execute something each time it fails. It is failing at all, you would want to know about the issue and fix it. Having a loop to always just keep trying is not the right way to go here.
I'd do what Ovidiu Pacurar suggests, only I'd use a foreach loop and leave dealing with array indexes up to the compiler.
Simple delegate approach:
Action<Action> tryForever = (action) => {
bool success;
do {
try {
action();
success = true;
} catch (Exception) {
// should probably log or something here...
}
} while (!success);
};
void DoEverything() {
tryForever(DoThis);
tryForever(NowDoThat);
tryForever(NowDoThis);
tryForever(MoreWork);
tryForever(AndImSpent);
}
Stack approach:
void DoEverything() {
Stack<Action> thingsToDo = new Stack<Action>(
new Action[] {
DoThis, NowDoThat, NowDoThis, MoreWork, AndImSpent
}
);
Action action;
while ((action = thingsToDo.Pop()) != null) {
bool success;
do {
try {
action();
success = true;
} catch (Exception) {
}
} while (!success);
}
Related
I have a new application that contains great amount of try-catch blocks. I am interested in if it is possible to write code which somehow attachs SaveExceptionInDatabase method to every catch-block I have used in my application.
try
{
//some actions
}
catch(exception e)
{
SaveExceptionInDatabase(e,DateTime.now(),CurrentUser);
ShowFriendlyNotification();
}
I think it will be helpful to easily remove bugs from my application, because I have noticed for several times that after the exception is thrown, attempting to perform the same operation second time finishes with success.
EDIT:
I am using WPF With Caliburn.Micro
You could use PostSharp and handle the exceptions. Here are some related articles that show how it can be done. This method seems really cool because you can just add an attribute to your classes an have the exceptions handled.
[DatabaseExceptionWrapper]
http://www.postsharp.net/blog/post/Day-1-e28093-OnExceptionAspect
http://www.postsharp.net/blog/post/Improve-Exception-Handling-and-Caching-using-PostSharp
You can use something like:
private void HandleDbException(Action action)
{
try
{
action();
}
catch (Exception e)
{
SaveExceptionInDatabase(e, DateTime.now(), CurrentUser);
ShowFriendlyNotification();
}
}
And then
HandleDbException(() =>
{
//some actions1
});
HandleDbException(() =>
{
//some actions2
});
...
It won't apply the pattern to each try/catch block in your code but at least avoids repeating the catch block.
Is there any way to tell the C# compiler that a function never returns? I'm running into the following problem. This is a boiled down version for simplicity.
public int myMethod()
{
try
{
return anythingHere();
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
'package.class.myMethod()' not all code paths return a value.
If not, is there a general way to frame this sort of thing other than inserting unreachable code? Having a 'return 0' or somesuch after the Exit just seems ridiculous to me. As far as I know there is no way that a function can return from an Environment.Exit call, so no return value is needed if that branch is taken (if it threw an exception the function still wouldn't need to have returned a value).
EDIT:
Maybe something like this?
public T MyExit<T>()
{
Environment.Exit(1);
return default(T);
}
Still not entirely satisfactory though.
C# does not support this.
In fact, it is impossible to do this in the general case.
Make the method void, and pass in an object that contains the 'anythingHere' type of information you need as an out type, so that it can be set, but the method itself won't actually return anything.
public void myMethod(out anythingObject)
{
try
{
anything = new anythingObject(stuff goes here);
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
I'm not sure if it's what you're looking for, but this would avoid unreachable code:
public int myMethod()
{
int retVal = 0;
try {
retVal = anythingHere();
} catch {
Environment.Exit(1);
}
return retVal;
}
It might be better to throw an exception than to call Environment.Exit. If someone else used your class, and their process suddenly shut down, they'd be pretty surprised. By throwing an exception you can at least explain why the problem happened.
At the top level entry point of your app (i.e., Main) you could then set up a global exception handler (AppDomain.UnhandledException) that handles all exceptions and calls Environment.Exit.
Make it a void, instead of an int.
public void myMethod(out int i)
{
try
{
i = anythingHere();
}
catch
{
Environment.Exit(1);
}
}
In Python, there is this useful exception handling code:
try:
# Code that could raise an exception
except Exception:
# Exception handling
else:
# Code to execute if the try block DID NOT fail
I think it's useful to be able to separate the code that could raise and exception from your normal code. In Python, this was possible as shown above, however I can't find anything like it in C#.
Assuming the feature or one like it doesn't exist, is it standard practice to put normal code in the try block or after the catch block?
The reason I ask is because I have the following code:
if (!IsReadOnly)
{
T newobj;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
}
Which requires the normal code to be in the try block because otherwise if an exception was raised and subsequently handled, newobj would be unassigned, but it feels quite unnatural to have this much code in the try block which is unrelated to the DataPortalException. What to do?
Thanks
I would prefer to see the rest of the code outside the try/catch so it is clear where the exception you are trying to catch is coming from and that you don't accidentally catch an exception that you weren't trying to catch.
I think the closest equivalent to the Python try/catch/else is to use a local boolean variable to remember whether or not an exception was thrown.
bool success;
try
{
foo();
success = true;
}
catch (MyException)
{
recover();
success = false;
}
if (success)
{
bar();
}
But if you are doing this, I'd ask why you don't either fully recover from the exception so that you can continue as if there had been success, or else fully abort by returning an error code or even just letting the exception propagate to the caller.
Barbaric solution: create an Else class derived from Exception, throw an instance of it at the end of the try block, and use catch (Else) {...} to handle the other stuff.
I feel so dirty.
This will might get downvoted but doesn't c# have goto(note I have almost no c# knowledge so I have no idea if this works).
what about something like
try
{
...
}
catch(Exception ex)
{
...
goto Jump_past_tryelse
}
...//Code to execute if the try block DID NOT fail
Jump_past_tryelse:
...
C# does not have such a concept, so you are just left with three options,
put the else code inside the try.
put the else code outside the try catch block, use a local variable to indicate success or failure, and an if block around your else code.
put the else code in the finally block, use a local variable to indicate success or failure, and an if block arount you else code.
Allow me to repeat an idea from a similar StackOverflow question. You cannot do this directly, but you can write a method that encapsulates the behavior you need. Look at the original question to see how to implement the method (if you're not familiar with lambda expressions and Func delegates). The usage could look like this:
TryExceptRaise(() => {
// code that can throw exception
}, (Exception e) => {
// code to run in case of an exception
return (...);
}, () => {
// code to run if there is no exception
return (...);
});
Just put your "else" block before the catch. Then, it will only execute if code execution reaches that point:
try
{
fee();
fi();
foe();
fum();
/// put your "else" stuff here.
/// It will only be executed if fee-fi-foe-fum did not fail.
}
catch(Exception e)
{
// handle exception
}
Given that, I fail to see the use of try..catch...else unless there's something vital missing from the OP's description.
With C# version 7, you could use local functions to emulate this behaviour:
Example 1: (since C# version 7)
void Main()
{
void checkedCode()
{
try
{
foo();
}
catch (Exception ex)
{
recover();
return;
}
// ElseCode here
}
checkedCode();
}
If you prefer lambda syntax, you could also declare a run method
void Run(Action r) { r(); }
which only needs to be there once in your code, and then use the pattern for anonymous methods as follows
Example 2: (older C# versions and C# version 7)
Run(() => {
try
{
foo();
}
catch (Exception)
{
recover();
return;
}
// ElseCode here
});
whereever you need to enclose code in a safe context.
Try it in DotNetFiddle
Notes:
In both examples a function context is created so that we can use return; to exit on error.
You can find a similar pattern like the one used in Example 2 in JavaScript: Self-invoking anonymous functions (e.g. JQuery uses them). Because in C# you cannot self-invoke, the helper method Run is used.
Since Run does not have to be a local function, Example 2 works with older C# versions as well
You could do something like this:
if (!IsReadOnly)
{
T newobj = null;
try
{
newobj = DataPortal.Update<T>(this);
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
if (newobj != null)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
that would be the empty statement like hits
try
{
somethingThatCanThrow();
}
catch(Exception ex)
{
LogException(ex);
return;
}
ContinueFlow();
if (!IsReadOnly)
{
T newobj;
bool Done;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
Done = true;
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
Done = false;
}
finally
{
if (newobj != null && Done == false)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
}
I've noticed this problem happening a lot in most things I do, so I'm thinking there must be a design pattern for this.
Basically if an exception is thrown, attempt to solve the problem and retry. If I place it in the try, all it will do is catch the exception, but I want to retry whatever it was doing and if it fails again, retry again a certain number of times.
Is there a common pattern for this sort of stuff?
check this SO answer.. hope that helps u
Cleanest way to write retry logic?
public static class RetryUtility
{
public static void RetryAction(Action action, int numRetries, int retryTimeout)
{
if(action == null)
throw new ArgumenNullException("action");
do
{
try
{
action();
return;
}
catch
{
if(numRetries <= 0)
throw; // Avoid silent failure
else
{
Thread.Sleep(retryTimeout);
numRetries--;
}
}
}
while(numRetries > 0);
}
}
Call
RetryUtility.RetryAction( () => SomeFunctionThatCanFail(), 3, 1000 );
Credit goes to LBushkin
This runs indefinately but it would be easy to add a loop counter to the while clause
var solved = false;
var tries = 0;
while (!solved)
{
try
{
//Do Something
solved = true;
}
catch
{
//Fix error
}
finally
{
if(solved || IsRediculous(tries))
break;
tries++;
}
}
try/catch inside a loop, with a counter for retries?
EDIT: And your requirement of "retry whatever it was doing," you need custom logic for that, how to retry varies wildly (ie, reopen a stream, recreate the object, pause for X milliseconds, etc...), so you need it's own try/catch inside a loop for every atomic operation.
By "atomic operation" I mean a set of related statements, such as read a file. The whole file read into memory might be an atomic operation, for example.
On some limited basis, you might want to put your try/catch into a loop, and force break if is ultimately successful. Such might be for internet access testing and you want user to have another attempt at connection.
Something like this, maybe:
int MAX_RETRIES = 5;
for (var attempt=1; attempt <= MAX_RETRIES; attempt++) {
try {
DoSomethingThatMightThrow();
}
catch (AnExceptionIKnowHowToHandle) {
if (attempt < MAX_RETRIES)
continue;
throw;
}
}
Depends what you are trying, but typically you want to check for the possibility of an exception happening PRIOR to executing the code that could cause an exception.
For example, check that a file exists before accessing it, and create it (or whatever) if it doesn't.
Are you sure exception handling is the proper methodology here? If you can "solve the problem" you can probably detect the error condition prior to calling the exception-generatiing code.
Exception handling is most natural for things which are truly exceptional. A failed Internet connection (as in the previous answer) is something that can be detected and handled before calling exception-throwing code.
Yes, it is quite common to have a loop with a number of retries where you break out of the loop on success. A couple of things:
You might want to add a delay before retrying so that you don't use up all your retries in just a few milliseconds before the temporary problem had time to fix itself.
If you eventually fail, you should throw the first exception you caught, not the last one. The second exception could be the result of failing to recover correctly from the first failure and might not help to debug the original problem.
Coding what others have already mentioned:
var success = false;
var attempts = 0;
var maxAttempts = 0;
do {
attempts++;
try {
/* your code */
success = condition;
} catch(SuperciliousException e) {
/* recover */
}
} while(!success && attempts < maxAttempts);
I have the need to do some logging within my code. I'm required to use an internal company-developed library to record some information. Here's how it works.
Recorder recorder = Recorder.StartTiming();
DoSomeWork();
recorder.Stop(); // Writes some diagnostic information.
To ensure that Stop() is always called, I created a wrapper class that allows a clean "using" block.
using (RecorderWrapper recorderWrapper = new RecorderWrapper) // Automatically calls Recorder.StartTiming() under the covers
{
DoSomeWork();
} // When the recorderWrapper goes out of scope, the 'using' statement calls recorderWrapper.Dispose() automatically - which calls recorder.Stop() under the covers
it's worked well so far. However, there's a change my company is requiring, that would look something like this on the original code:
Recorder recorder = Recorder.StartTiming();
try
{
DoSomeWork();
}
catch (Exception ex)
{
recorder.ReportFailure(ex); // Write out some exception details associated with this "transaction"
}
recorder.Stop(); // Writes some diagnostic information.
I'd like to avoid try/catches in all my 'using' scope blocks with RecorderWrapper. Is there a way I can accomodate the "ReportFailure()" call and still leverage the 'using' scope block?
Specifically, I want everyone on my team to "fall into a pit of success", i.e. make it easy to do the right thing. To me, this means making it really hard to forget to call recorder.Stop() or forget the try/catch.
Thanks!
You might be able to create a method on the recorder to hide this:
public void Record(Action act)
{
try
{
this.StartTiming();
act();
}
catch(Exception ex)
{
this.ReportFailure(ex);
}
finally
{
this.Stop();
}
}
So your example would then just be:
recorder.Record(DoSomeWork);
You could always try something like:
Edit by 280Z28: I'm using a static StartNew() method here similar to Stopwatch.StartNew(). Make your Recorder class IDisposable, and call Stop() from Dispose(). I don't think it gets any more clear than this.
using (Recorder recorder = Recorder.StartNew())
{
try
{
DoSomeWork();
}
catch (Exception ex)
{
recorder.ReportFailure(ex);
}
}
You could continue to use the RecorderWrapper you have, but add a TryExecuting method that accepts a lambda of what you want to happen add runs it in a try/catch block. eg:
using (RecorderWrapper recorderWrapper = new RecorderWrapper) // Automatically calls Recorder.StartTiming() under the covers
{
recorderWrapper.TryExecuting(() => DoSomeWork());
}
Inside RecorderWrapper:
public void TryExecuting(Action work)
{
try { work(); }
catch(Exception ex) { this.ReportFailure(ex); }
}
You could copy the pattern used by TransactionScope, and write a wrapper that must be actively completed - if you don't call Complete(), then the Dispose() method (which gets called either way) assumes an exception and does your handling code:
using(Recorder recorder = Recorder.StartTiming()) {
DoSomeWork();
recorder.Complete();
}
Personally, though, I'd stick with try/catch - it is clearer for maintainers in the future - and it provides access to the Exception.
No, a using block is only syntactic sugar for a try/finally block. It doesn't deal with try/catch. At that point you're going to be left with handling it yourself since it looks like you need the exception for logging purposes.
A using block is effectively a try/finally block that calls dispose on the object in question.
So, this:
using(a = new A())
{
a.Act();
}
is (i think, exactly) equivalent to this:
a = new A();
try
{
a.Act();
}
finally
{
a.Dispose();
}
And you can tack your catches onto the end of the try block.
Edit:
As an alternative to Rob's solution:
Recorder recorder = Recorder.StartNew()
try
{
DoSomeWork();
}
catch (Exception ex)
{
recorder.ReportFailure(ex);
}
finally
{
recorder.Dispose();
}
Oops, I hadn't noticed that a new instance of Recorder was being created by StartTiming. I've updated the code to account for this. The Wrap function now no longer takes a Recorder parameter but instead passes the recorder it creates as an argument to the action delegate passed in by the caller so that the caller can make use of it if needed.
Hmmm, I've needed to do something very similar to this pattern, lambdas, the Action delegate and closures make it easy:
First define a class to do the wrapping:
public static class RecorderScope
{
public static void Wrap(Action<Recorder> action)
{
Recorder recorder = Recorder.StartTiming();
try
{
action(recorder);
}
catch(Exception exception)
{
recorder.ReportFailure(exception);
}
finally
{
recorder.Stop();
}
}
}
Now, use like so:
RecorderScope.Wrap(
(recorder) =>
{
// note, the recorder is passed in here so you can use it if needed -
// if you never need it you can remove it from the Wrap function.
DoSomeWork();
});
One question though - is it really desired that the catch handler swallows the exception without rethrowing it? This would usually be a bad practice.
BTW, I'll throw in an addition to this pattern which can be useful. Although, it doesn't sound like it applies to what you're doing in this instance: Ever wanted to do something like the above where you want to wrap some code with a set of startup actions and completion actions but you also need to be able to code some specific exception handling code. Well, if you change the Wrap function to also take an Action delegate and constrain T to Exception, then you've got a wrapper which allows user to specify the exception type to catch, and the code to execute to handle it, e.g.:
public static class RecorderScope
{
public static void Wrap(Action<Recorder> action,
Action<Recorder, T1> exHandler1)
where T1: Exception
{
Recorder recorder = Recorder.StartTiming();
try
{
action(recorder);
}
catch(T1 ex1)
{
exHandler1(recorder, ex1);
}
finally
{
recorder.Stop();
}
}
}
To use.. (Note you have to specify the type of exception, as it obviously cannot be inferred. Which is what you want):
RecorderScope.Wrap(
(recorder) =>
{
DoSomeWork();
},
(recorder, MyException ex) =>
{
recorder.ReportFailure(exception);
});
You can then extend this pattern by providing multiple overloads of the Wrap function which take more than one exception handler delegate. Usually five overloads will be sufficient - it's pretty unusual for you to need to catch more than five different types of exceptions at once.
Don't add another level of indirection. If you need to catch the Exception, use try..catch..finally and call Dispose() in the finally block.