【发布时间】:2013-10-17 16:59:10
【问题描述】:
我正在 csharp (.net 4.0) 中构建一个消息传递应用程序,我的班级有发送/接收消息的基本方法:
void sendMessage( string msgBody, string properties);
object getNextMessage();
object getMessageById( string msgId);
这些方法中的每一个都依赖于底层连接;如果连接过时,我会使用 try/catch 和一些重试逻辑进行额外尝试,如下所示:
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;
}
由于重试逻辑是通用的,我想避免在每个方法中重复相同的代码。我想创建一个通用的重试函数并执行以下操作:
public object makeAttempt( CodeBlock codeBlock){
while( retryAttempts < MAX_ATTEMPTS){
retryAttempts++;
try{
return codeBlock.invoke()
}catch(Exception e){
}
}
return null;
}
..我想像这样使用makeAttempt,或者类似的东西:
public object getNextMessage(){
makeAttempt() => {
return connection.getMessage("queueName");
}
}
我查看了this,但它涉及将整个函数作为参数传递,我没有这样做。我还查看了.net Lambda Expressions,但我没有看到连接。
我没有做太多 C#,所以请原谅 n00b 的问题 :-)
【问题讨论】:
-
您已经准确查找了解决此问题所需的工具。 lambda 只不过是一种用于创建新方法的简洁语法,这正是您想要的。
-
代码块或匿名函数 (lambda) 正是您所需要的。这就是你传递代码块的方式
-
@Servy:字面意思尚未完成 -
makeAttempt和getNextMessage中的代码还不能编译。 -
@JonSkeet 对,我的意思是他已经有了问题的答案。措辞不好。
-
旁注;与其忽略重试导致的所有异常,不如考虑保留它们并在所有引退失败的情况下将它们重新抛出
AggregateException,而不是返回null。既是因为null可能是函数调用的有效结果,又因为调用者有关于失败原因的有意义的信息。