如何在有限数量上重试“try-catch”并延迟它?

时间:2013-08-11 21:46:32

标签: android try-catch

我使用此代码在两个设备之间传输数据。

public void run() {

        try {
            Socket s = new Socket(myIpAddress, SERVERPORT);

            // outgoing stream redirect to socket
            OutputStream out = s.getOutputStream();

            PrintWriter output = new PrintWriter(out);
            output.println("DLS");
            BufferedReader input = new BufferedReader(new InputStreamReader(
                    s.getInputStream()));

            // read line(s)
            String st = input.readLine();
            // . . .
            // Close connection
            s.close();

        } catch (UnknownHostException e) {
            run();
            e.printStackTrace();
        } catch (IOException e) {
            run();
            e.printStackTrace();
        }

    }

我的问题是我必须首先启动服务器,之后,我可以启动客户端以成功连接。

public void run()

我将run()添加到UnknownHostExceptionIOException。 它在其他代码中工作正常,但在这里我得到了StackOverFlowError。 我怎样才能让它在有限的数量上重试并且每隔X秒尝试一次?

我尝试过这种方式,因为run()Thread.sleep(5000);因未处理的异常而哭泣。当我启动该服务时,该应用程序被冻结。

public void run() throws UnknownHostException, IOException {

        Socket s = new Socket(myIpAddress, SERVERPORT);

        // outgoing stream redirect to socket
        OutputStream out = s.getOutputStream();

        PrintWriter output = new PrintWriter(out);
        output.println("DLS");
        s.close();

    } 

@Override
public void onCreate() {
    for (int i = 0; i < 10; i++) {
        try {
            run();
            break; // no exception: break out of the loop.
        }
        catch (IOException e) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }

3 个答案:

答案 0 :(得分:0)

在catch中调用run()之前,你可以这样做 -

Thread.sleep(1000); // 1000 milli second = 1 second

这将使线程在再次调用run之前休眠一秒钟。此外,你不应该永远尝试,因为这会导致错误的递归调用,并且堆栈中没有足够的空间可以继续执行任何更多的代码执行,包括打印错误。也许你应该尝试最多5到10次,间隔3秒,然后放弃。

当没有虚拟内存可供执行时,会发生堆栈溢出错误。

假设您从创建方法调用运行 -

private static final int MAX_TRY = 5;

public void create(){

    for(int i = 0; i < MAX_TRY; i++){    
        if(run()){ // if run call returns true, then get out of the loop        
            break;        
        } else {           
           Thread.sleep(1000); // Wait for a second before next try       
        }    
    }
}


public boolean run() {    

    boolean isSuccessful = false;

    try {

        Socket s = new Socket(myIpAddress, SERVERPORT);

        // outgoing stream redirect to socket
        OutputStream out = s.getOutputStream();

        PrintWriter output = new PrintWriter(out);
        output.println("DLS");
        BufferedReader input = new BufferedReader(new InputStreamReader(
                s.getInputStream()));

        // read line(s)
        String st = input.readLine();
        // . . .

        isSuccessful = true;

    } catch (Exception e) {            
        e.printStackTrace();            
    } finally {
        s.close();
    }

    return isSuccessful;

}

答案 1 :(得分:0)

你只需要一个循环(IMO,比递归更容易理解):

for (int i = 0; i < MAX_ATTEMPTS; i++) {
    try {
        run();
        break; // no exception: break out of the loop.
    }
    catch (UnknownHostException | IOException e) {
        Thread.sleep(DELAY_BETWEEN_ATTEMPTS_IN_MILLIS);
    }
}

当然,您不能再从run()方法本身捕获异常。

答案 2 :(得分:0)

你正在编写一个函数,在没有延迟的情况下在失败时回避。这是不可取的,原因有两个,其中一个原因是你可以吹掉调用堆栈(如你所见)。

一般来说,我建议将可能失败的代码拉出到自己的函数中,然后将其专门返回成功与可重试失败相对于其他失败(例如使用自定义“RetryableFailure”子类的异常)。然后你可以从代码中调用它,如果有必要,可以在延迟之后重试。

E.g。

class RetryableException extends Exception {
    public RetryableException(Throwable: underlying) {
        ...
    }
}


public void tryIt() throws RetryableException {

    Socket s = null;
    try {
        s = new Socket(myIpAddress, SERVERPORT);

        // outgoing stream redirect to socket
        OutputStream out = s.getOutputStream();

        PrintWriter output = new PrintWriter(out);
        output.println("DLS");
        BufferedReader input = new BufferedReader(new InputStreamReader(
                s.getInputStream()));

        // read line(s)
        String st = input.readLine();
        // . . .

    } catch (UnknownHostException e) {
        throw new RetryableException(e);
    } catch (IOException e) {
        throw new RetryableException(e);
    } finally {
        if (s != null) {
            s.close();
        }
    }
}


public void run() {
    boolean succeeded = false;
    while (! succeeded) {
        try {
            tryIt();
            succeeded = true;
        } catch (RetryableException e) {
            // log
            Thread.sleep(1000);
        }
    }
}

另请注意以下事项: