Try, Catch Problem
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.
Basic开发者_开发问答ally 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);
精彩评论