I'm building a messaging app in csharp (.net 4.0), my class has basic methods for sending/receiving messages:
void sendMessage( string msgBody, string properties);
object getNextMessage();
object getMessageById( string msgId);
Each of these methods depends on an underlying connection; if the connection is stale, I use try/catch and some retry logic to make additional attempts, something like this:
public object getNextMessage(){
object nextMessage = null;
int retryAttempts = 0;
int MAX_ATTEMPTS = 3;
while( retryAttempts < MAX_ATTEMPTS){
retryAttempts++;
try{
nextMessage = connection.getMessage("queueName");
}catch(Exception e){
}
}
return nextMessage;
}
Since the retry logic is generic, I want to avoid repeating the same code in each method. I want to create a common retry function and do something like this:
public object makeAttempt( CodeBlock codeBlock){
while( retryAttempts < MAX_ATTEMPTS){
retryAttempts++;
try{
return codeBlock.invoke()
}catch(Exception e){
}
}
return null;
}
..I want to use makeAttempt
like this, or something similar:
public object getNextMessage(){
makeAttempt() => {
return connection.getMessage("queueName");
}
}
I reviewed this, but it relates to passing entire functions as arguments, which I'm not doing. I also reviewed .net Lambda Expressions, but I'm not seeing a connection.
I haven't done much C# so forgive the n00b question :-)
You're nearly there at the end - you just need to enclose the lambda expression in ()
as it's a method argument. You also need to use the return value from makeAttempt
to provide a return value for your getNextMessage
method. So:
public object getNextMessage(){
return makeAttempt(() => {
return connection.getMessage("queueName");
});
}
Or more simply, use an expression lambda:
public object getNextMessage(){
return makeAttempt(() => connection.getMessage("queueName"));
}
This is all assuming that CodeBlock
is a delegate type, of course, e.g.
public delegate object CodeBlock();
You also need to change makeAttempt
to call Invoke
rather than invoke
- C# is case-sensitive. I'd strongly urge you to follow .NET naming conventions, too, where methods are PascalCased
instead of camelCased
.
EDIT: As noted in comments, you could make this generic:
public T CallWithRetries<T>(Func<T> function)
{
for (int attempt = 1; attempt <= MaxAttempts; attempt++)
{
try
{
return function();
}
catch(Exception e)
{
// TODO: Logging
}
}
// TODO: Consider throwing AggregateException here
return default(T);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With