我有一个功能包含服务器的Web服务调用,由于网络中的一些干扰,该服务有时失败(无法连接远程服务器错误)。代码在try catch块中。我想在try块中重新运行Web服务调用,以便成功完成Web调用。
答案 0 :(得分:14)
const int MaxRetries = 5;
for(int i = 0; i < MaxRetries; i++)
{
try
{
// do stuff
break; // jump out of for loop if everything succeeded
}
catch(Exception)
{
Thread.Sleep(100); // optional delay here
}
}
答案 1 :(得分:12)
bool success = false;
int retry = 0;
while (!success && retry<3)
{
try{
// web service calls
success = true;
} catch(Exception) {
retry ++;
}
}
答案 2 :(得分:4)
public void Connect()
{
Connect(1);
}
private void Connect(int num)
{
if (num > 3)
throw new Exception("Maximum number of attempts reached");
try
{
// do stuff
}
catch
{
Connect(num++);
}
}
答案 3 :(得分:3)
你可以像这样在try catch块周围放一个循环:
bool repeat = true
while( repeat){
repeat = false;
try
{
...
}
catch( Exception )
{
repeat = true;
}
}
答案 4 :(得分:3)
我想你在这里有答案。我只想根据我对此问题的丰富经验添加一些建议。
如果您将日志记录添加到catch
块,则可以确定Web服务调用失败的频率,以及所有尝试的次数。 (可能会在web.config
中进行切换,以便在问题解决后关闭此注销。)
例如,如果Web服务提供商在您的组织内,例如在Intranet上,则该信息可能在与系统管理员讨论时非常有用。
此外,如果您发现呼叫仍然经常失败,您可能会在catch
中引入延迟,以便不立即重试。您可能只想在最后的尝试中这样做。有时值得等待用户,他们不想丢失他们刚刚输入的所有数据。
最后,根据具体情况,您可以在UI中添加“重试”按钮,以便用户可以继续尝试。用户可以选择等待五分钟以使网络问题自行清除,然后单击“重试”。
答案 5 :(得分:2)
在while循环中包装try / catch。成功时设置一个标志以退出while(或仅break
)。确保你有某种重试限制,因此它不会永远持续下去。
答案 6 :(得分:2)
while (true)
{
try
{
// call webservice
// handle results
break;
}
catch (TemporaryException e)
{
// do any logging you wish
continue;
}
catch (FatalException e)
{
// do any logging you wish
break;
}
}
如果要限制重试次数,请更改while
循环中的终止条件。
答案 7 :(得分:2)
void Method()
{
do
{
try
{
DoStuff();
return;
}
catch (Exception e)
{
// Do Something about exception.
}
}
while (true);
}
答案 8 :(得分:2)
如果您发现自己希望在代码中频繁地执行此操作,则可以考虑实现一个可重用的类,该类封装了“遇到错误时重新尝试”逻辑。这样,您可以确保整个代码库中的行为标准化,而不是每次都重复。
Dan Gartner's blog上有一个很好的例子:
public class Retrier<TResult>
{
public TResult Try(Func<TResult> func, int maxRetries)
{
return TryWithDelay(func, maxRetries, 0);
}
public TResult TryWithDelay(Func<TResult> func, int maxRetries, int delayInMilliseconds)
{
TResult returnValue = default(TResult);
int numTries = 0;
bool succeeded = false;
while (numTries < maxRetries)
{
try
{
returnValue = func();
succeeded = true;
}
catch (Exception)
{
//todo: figure out what to do here
}
finally
{
numTries++;
}
if (succeeded)
return returnValue;
System.Threading.Thread.Sleep(delayInMilliseconds);
}
return default(TResult);
}
}
答案 9 :(得分:1)
嗯,最简单的方法是将代码复制到catch块,对吧? 另一种方法可能如下:
private void YourMethodThatTriesToCallWebService()
{
//Don't catch errors
}
public void TryToCallWebService(int numTries)
{
bool failed = true;
for(int i = 0; i < numTries && failed; i++)
{
try{
YourMethodThatTriesToCallWebService();
failed = false;
}catch{
//do nothing
}
}
}
答案 10 :(得分:0)
您应该将整个catch块放入while语句中:
while(retryCount < MAX_RETRY && !success)
{
try
{
//do stuff , calling web service
success = true;
}
catch
{
retryCount++
success = false;
}
}