我有一种定期(例如每10秒一次)尝试连接服务器并从中读取一些数据的方法。服务器可能不会一直可用。如果服务器不可用,则该方法抛出异常。
实现不抛出异常的包装器方法的最佳方法是什么,除非服务器至少在一分钟内不可用?
答案 0 :(得分:7)
跟踪您上次成功到达服务器的时间。如果服务器抛出异常,请捕获它并与上次到达服务器时进行比较。如果该时间超过一分钟,请重新抛出异常。
答案 1 :(得分:3)
在伪代码中。
//Create Timer
//Start Timer
bool connected = false;
while (!connected)
try {
//Connect To DB
connected = true;
}
catch (Exception ex) {
if (more than 1 minute has passed)
throw new Exception(ex);
}
}
答案 2 :(得分:1)
您必须记录最初尝试连接到服务器的时间,然后捕获异常。如果捕获异常的时间超过原始时间+ 1分钟,则重新抛出异常。如果没有,请重试。
答案 3 :(得分:1)
理想情况下,您可以对服务器的调用设置超时。如果没有在catch块中执行thread.sleep(600)并再次尝试,如果第二个没有返回则会失败。
答案 4 :(得分:1)
请记住,异常处理只是通常的“返回”系统的非常专业的使用。 (有关更多技术细节,请阅读“monad”。)如果您想要发出的异常情况不适合Java的异常处理系统,则可能不适合使用例外。
您可以通常的方式跟踪错误情况:保留状态变量,根据需要使用成功/失败信息进行更新,并在状态发生变化时做出相应的响应。
答案 5 :(得分:0)
您可以进行重试计数,如果满足所需的计数(在您的情况下为6),则抛出异常
int count = 0;
CheckServer(count);
public void CheckServer(count) {
try
{
// connect to server
}
catch(Exception e)
{
if(count < MAX_ATTEMPTS) {
// wait 10 seconds
CheckServer(count++)
}
else {
throw e;
}
}
}
答案 6 :(得分:0)
您可以为服务器连接是否成功设置一个布尔变量,并在异常处理程序中检查它,如下所示:
class ServerTester : public Object
{
private bool failing;
private ServerConnection serverConnection;
private Time firstFailure;
public ServerTester(): failing(false)
{
}
public void TestServer() throws ServerException
{
try
{
serverConnection.Connect();
failing = false;
}
catch (ServerException e)
{
if (failing)
{
if (Time::GetTime() - firstFailure > 60)
{
failing = false;
throw e;
}
}
else
{
firstFailure = Time::GetTime();
failing = true;
}
}
}
}
我不知道API的实际时间是什么,因为自从我上次使用Java以来已经有一段时间了。这将按照你的要求行事,但有些事情似乎并不合适。对异常进行轮询对我来说有点倒退,但是既然你正在处理服务器,我就无法想到任何其他方式。