如何在不中断线程执行的情况下处理TIdHTTP致命网络错误?

时间:2014-04-25 20:07:39

标签: multithreading delphi exception-handling indy

我想详细说明如何正确处理TThread TIdHTTP程序中Execute引发的致命网络异常。

我的应用在while..do程序中运行Execute循环。每个循环都会进行TIdHTTP.Get()调用。异常在循环级别处理。还有一个on E: Exception do的上级处理程序(Execute级别)。

该方案假定在活动网络操作期间发生致命网络错误(即适配器中断,"通过对等方连接重置"等)。

序列化10个线程以从循环内部发出TIdHTTP.Get()个请求。当家用路由器意外挂起时,该应用程序在笔记本电脑上运行。来了#10054。假设网络在10分钟内返回。我想确保在网络突然死亡的情况下,每个线程都会以某种方式:

  1. 检测(嗯,这是最简单的)
  2. 等待网络回来。
  3. 确保网络正常运行。
  4. 重新建立连接并恢复所有网络连接。
  5. 继续循环。
  6. 期望的结果是保持线程正常运行并且能够解决临时网络问题。线程必须定期检查网络是否恢复。如果是,异常处理程序必须恢复所有网络调用线程的RestoreNetworkConnection,然后继续循环。

    我绝对不想要的是 - 停止线程'执行。

    问题

    1. 我应该拦截哪些事件/例外来处理致命的网络错误?
    2. Execute内放置异常处理程序的位置?
    3. 重新建立连接回正常状态的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

最简单的方法是做这样的事情:

procedure TMyThread.Execute;
var
  NetworkDown: Boolean;
begin
  NetworkDown := False;
  try
    while not Terminated do
    begin
      // wait for a successful HTTP response...
      repeat
        if Terminated then Exit;
        try
          IdHTTP.Get(...);
          Break;
        except
          on E: EIdHTTPProtocolException do begin
            // process HTTP error as needed...
          end;
          on E: EIdSocketError do begin
            NetworkDown := True;
            // process socket error as needed...
          end;
          on E: Exception do begin
            // process any other error as needed...
            raise;
          end;
        end;
        Sleep(1000);
      until False;

      // got a response, check if network was previously down
      if NetworkDown then
      begin
        NetworkDown := False;
        RestoreNetworkConnection;
      end;

      // now process HTTP response as needed ...
    end;
  except
    on Exception do begin
      // process fatal error as needed ...
    end;
  end;
end;