int noOfAttempts = 3;
void StartServer();
bool IsServerRunning();
我需要根据StartServer()
的结果重新尝试IsServerRunnig()
3次。像这样:
StartServer();
if (!IsServerRunning())
{
StartServer();
if (!IsServerRunning())
{
StartServer();
if (!IsServerRunning())
{
StartServer();
}
}
}
我不想使用for循环或上面那些丑陋的代码。有没有更好的方法呢?如果noOfAttempts
将来发生变化,我将不必更改我的代码?
编辑: 我期待“委托”概念中的某些内容(如果可能的话)。
答案 0 :(得分:7)
你可以使用while循环
int counter = 0;
while(counter < 3 && !IsServerRunning()) {
StartServer();
counter++;
}
答案 1 :(得分:7)
<强> UPD 强>:
看起来你真的想要(ed)一些简洁的方法来描述重试逻辑。在这种情况下,请查看瞬态故障处理库,例如Polly。
确定。
3.TimesUntil(IsServerRunning, StartServer);
在这里代表魔术:
public static class Extensions
{
public static void TimesWhile(this int count, Func<bool> predicate, Action action)
{
for (int i = 0; i < count && predicate(); i++)
action();
}
public static void TimesUntil(this int count, Func<bool> predicate, Action action)
{
for (int i = 0; i < count && !predicate(); i++)
action();
}
}
尊敬的downvoters: 这只是为了好玩,我永远不会为真正的项目编写这段代码。
答案 2 :(得分:6)
这里你没有循环......
private void Start(int numberOfAttempts)
{
if (numberOfAttempts == 0)
return;
StartServer();
if (!IsServerRunning())
Start(numberOfAttempts-1);
}
答案 3 :(得分:1)
正如大家已经注意到一段时间或for循环真的是解决这个问题最容易的部分。
如果您真的想为这些内容设置一些非常先进的内容,请查看trampoline function question或查看article from Bart。使用这种方法,您将能够避免循环(因此我认为在这种情况下不值得)。
答案 4 :(得分:0)
不确定
while (numRetries > 0 && !IsServerRunning) {
StartServer();
numRetries--;
}
如果您有冒险精神,也可以使用goto
; - )
答案 5 :(得分:0)
int numberOfAttempts = 3;
do
{
StartServer();
numberOfAttempts--;
}
while(!IsServerRunning() && numberOfAttempts > 0)
更新:因此这个操作密切相关,你可以创建方法
bool TryStartServer()
{
StartServer();
return IsServerRunning();
}
第二个,将尝试多次启动服务器(并返回操作结果)
bool TryStartServer(int numberOfAttemtps)
{
for(int attempt = 0; attempt < numberOfAttempts; attempt++)
if (TryStartServer)
return true;
return false;
}
答案 6 :(得分:0)
如果你真的想要你可以使用委托......(也许是为了可重用的东西?)
public void CallFunctionNTimes(Action func, int nTimes, params bool[] conditions) {
int callCounter = 0;
while (callCounter < nTimes && conditions.All(x => x == true)) {
func();
callCounter++;
}
}
用法:
CallFunctionNTimes(StartServer, 3, !IsServerRunning /* Other stuff too if you want */);
..与其他答案没有太大的不同,除了它可重复使用我猜:)
答案 7 :(得分:0)
do ... while(false)循环怎么样? (开玩笑,但我以前在代码中看到了它)
int numTries;
do
{
if(numTries == 0)
break;
StartServer();
numTries--;
if (!IsServerRunning)
continue;
} while (false);
答案 8 :(得分:0)
我可能会将它作为StartServer
方法本身的内置功能。像这样的东西(只是一个概念证明):
public class ServerNotRunningException : Exception { /*No content here*/ }
public void StartServer(int attempts = 3)
{
try
{
//attempt to start server
if(!IsServerRunning()) // or check something available in your method
throw new ServerNotRunningException();
}
catch(ServerNotRunningException ex)
{
// you should log ex.ToString() here!
if(attempts>0) StartServer(attempts-1); //try again!
else throw new ServerNotRunningException(); //mission failed, bubble up!
}
}
用法:
StartServer();
//or, to make it try i.e. 5 times
StartServer(5);
答案 9 :(得分:-1)
最好让重试逻辑与主代码完全分开:
void Attempt(Action action, Func<bool> ensure, int noOfAttempts)
{
while (noOfAttempts-- > 0 && !ensure())
{
action();
}
}
然后:
Attempt(action:StartServer, ensure:IsServerRunning, noOfAttempts:3)
答案 10 :(得分:-1)
只是为了好玩
var calls = Enumerable.Repeat<List<string>>(new List<string>() { "IsServerRunning", "StartServer" }, noOfAttempts).ToList();
calls.ForEach(new Action<List<string>>(
delegate(List<string> item)
{
// Use reflection here to create calls to the elements of item
}
));