[英]How to pass code blocks (not full methods) as arguments in C#?
I'm building a messaging app in csharp (.net 4.0), my class has basic methods for sending/receiving messages: 我正在csharp(.net 4.0)中构建一个消息传递应用程序,我的类具有发送/接收消息的基本方法:
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:
如果连接是陈旧的,我使用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;
}
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: ..我想像这样使用
makeAttempt
,或类似的东西:
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.
我还回顾了.net Lambda表达式 ,但我没有看到连接。
I haven't done much C# so forgive the n00b question :-) 我没有做太多C#所以请原谅n00b问题:-)
You're nearly there at the end - you just need to enclose the lambda expression in ()
as it's a method argument. 你最后几乎就在那里 - 你只需要将lambda表达式括在
()
因为它是一个方法参数。 You also need to use the return value from makeAttempt
to provide a return value for your getNextMessage
method. 您还需要使用
makeAttempt
的返回值为getNextMessage
方法提供返回值。 So: 所以:
public object getNextMessage(){
return makeAttempt(() => {
return connection.getMessage("queueName");
});
}
Or more simply, use an expression lambda: 或者更简单地说,使用表达式lambda:
public object getNextMessage(){
return makeAttempt(() => connection.getMessage("queueName"));
}
This is all assuming that CodeBlock
is a delegate type, of course, eg 这是假设
CodeBlock
是委托类型,当然,例如
public delegate object CodeBlock();
You also need to change makeAttempt
to call Invoke
rather than invoke
- C# is case-sensitive. 您还需要更改
makeAttempt
以调用Invoke
而不是invoke
- C#区分大小写。 I'd strongly urge you to follow .NET naming conventions, too, where methods are PascalCased
instead of camelCased
. 我强烈建议您遵循.NET命名约定,其中方法是
PascalCased
而不是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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.