我在我的网络应用程序上使用xml Web服务,有时远程服务器无法及时响应。如果第一次尝试失败,我想出了重新请求的想法。为了防止循环,我想在2处限制并发请求。我想得到一个意见,如果我在下面做了什么,并且会按照我的预期工作。
public class ScEngine
{
private int _attemptcount = 0;
public int attemptcount
{
get
{
return _attemptcount;
}
set
{
_attemptcount = value;
}
}
public DataSet GetStat(string q, string job)
{
try
{
//snip....
attemptcount += attemptcount;
return ds;
}
catch
{
if (attemptcount>=2)
{
return null;
}
else
{
return GetStat(q, job);
}
}
}
}
答案 0 :(得分:1)
您忘记增加尝试次数。另外,如果第二次运行时出现任何错误,则不会被捕获(因此,将成为未处理的异常)。
答案 1 :(得分:1)
public class ScEngine
{
public DataSet GetStat(string q, string job)
{
int attemptCount;
while(attemptCount < 2)
{
try
{
attemptCount++;
var ds = ...//web service call
return ds;
}
catch {}
}
//log the error
return null;
}
}
答案 2 :(得分:1)
查看此链接。这是处理重试和超时的好方法。 http://timross.wordpress.com/2008/02/10/implementing-the-circuit-breaker-pattern-in-c/
答案 3 :(得分:0)
我不会为了重试而递归。此外,我不会抓住并忽略所有异常。我将了解哪些异常表明应该重试的错误,并且会捕获这些错误。正如你的代码所代表的那样,你将忽略严重的错误。
答案 4 :(得分:0)
你不想这样解决它。您只需在服务器上施加更多负载并导致更多超时。
您可以增加网络服务超时via httpRuntime。 Web服务通常会在一次调用中返回大量数据,因此我发现自己经常这样做。不要忘记增加客户愿意在客户端等待的时间。
答案 5 :(得分:0)
这是一个不使用递归但实现相同结果的版本。它还包括一个延迟,因此如果它打嗝,你可以给服务器恢复时间。
/// <summary>
/// The maximum amount of attempts to use before giving up on an update, delete or create
/// </summary>
private const int MAX_ATTEMPTS = 2;
/// <summary>
/// Attempts to execute the specified delegate with the specified arguments.
/// </summary>
/// <param name="operation">The operation to attempt.</param>
/// <param name="arguments">The arguments to provide to the operation.</param>
/// <returns>The result of the operation if there are any.</returns>
public static object attemptOperation(Delegate operation, params object[] arguments)
{
//attempt the operation using the default max attempts
return attemptOperation(MAX_ATTEMPTS, operation, arguments);
}
/// <summary>
/// Use for creating a random delay between retry attempts.
/// </summary>
private static Random random = new Random();
/// <summary>
/// Attempts to execute the specified delegate with the specified arguments.
/// </summary>
/// <param name="operation">The operation to attempt.</param>
/// <param name="arguments">The arguments to provide to the operation.</param>
/// <param name="maxAttempts">The number of times to attempt the operation before giving up.</param>
/// <returns>The result of the operation if there are any.</returns>
public static object attemptOperation(int maxAttempts, Delegate operation, params object [] arguments)
{
//set our initial attempt count
int attemptCount = 1;
//set the default result
object result = null;
//we've not succeeded yet
bool success = false;
//keep trying until we get a result
while (success == false)
{
try
{
//attempt the operation and get the result
result = operation.DynamicInvoke(arguments);
//we succeeded if there wasn't an exception
success = true;
}
catch
{
//if we've got to the max attempts and still have an error, give up an rethrow it
if (attemptCount++ == maxAttempts)
{
//propogate the exception
throw;
}
else
{
//create a random delay in milliseconds
int randomDelayMilliseconds = random.Next(1000, 5000);
//sleep for the specified amount of milliseconds
System.Threading.Thread.Sleep(randomDelayMilliseconds);
}
}
}
//return the result
return result;
}