断网后如何重新连接

时间:2023-02-04 17:28:45
data module的oncreate事件中

procedure TData1.DataModuleCreate(Sender: TObject);
var filename:string;
begin
filename:=ExtractFilePath(paramstr(0))+'myini.ini';
myinifile:=TInifile.Create(filename);
version:=myinifile.ReadString('ServerInfo','version','');
ADOConnection1.ConnectionString:= 'Provider=SQLOLEDB.1;Password='+myinifile.readstring('ServerInfo','SQLPwd','')+';Persist Security Info=True;User ID='+myinifile.readstring('ServerInfo','SQLUserID','')+';Initial Catalog='+myinifile.readstring('ServerInfo','SQLDBName','')+';Data Source='+myinifile.readstring ('ServerInfo','ServerIP','');
end;

窗体中U_ygbm 的刷新代码

adoquery1     (连接上面的ADOConnection1)
  with adoquery1 do
    begin
      close;
      sql.Clear;
      sql.Add('select * from tba_ygbm');
      open;
    end;


在进销存中如果网线断网后再刷新会提示连接失败,如果网络正常后也要退出整个程序后才能再进入操作,刷新也没用
有些程序可以实现重新连接,如何实现呢

29 个解决方案

#1


连接代码再执行一遍

#2


搞个TIMER控件,隔段时间检查一下是否连接正常,如果断开了,再执行一次连接代码 !

#3


把里面的 KeepConnection 属性给 False 了

以后用一次连一次

#4


我试试,有点麻烦

#5


  with adoquery1 do
begin
 Connection := data1.ADOConnection1;
 Close;
SQL.Clear;
      sql.Add('select tba_ygbm.*,tba_bmbm.bmmc from tba_ygbm left join tba_bmbm on tba_ygbm.bmbm=tba_bmbm.bmbm order by ygbm');
  try
    try
     data1.ADOConnection1.Connected := false;
      data1.ADOConnection1.Connected := true;
    except
    end;
    adoquery1.Open;
  except

  end;
end;


 还是不行

#6


var
  adoq : TADOQuery;
begin
  adoq := TADOQuery.Create(nil);
  adoq.Connection := dm.ADOConn;
  adoq.Close;
  adoq.SQL.Clear;
  adoq.SQL.Add('select * from cat where 1=0');
  try
    try
      if dm.ADOConn.Connected then  
        dm.ADOConn.Connected := false;
      dm.ADOConn.Connected := true;
    except
    end;
    adoq.Open;
  except

  end;
end;



或者
  try
      while dm.ADOConn.Connected=true do
      begin
        dm.ADOConn.Connected := false;
        application.ProcessMessages;
      end;
      while dm.ADOConn.Connected=false do
      begin
        dm.ADOConn.Connected := true;
        application.ProcessMessages;
      end;
    except
    end;
都可以,不过太影响速度了,有没有简单点办法

#7


这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考:
procedure TForm2.Timer4Timer(Sender: TObject);
var
  strError:string;
  ConnStr,ServerIp:string;
  tmpStrList :TStringList;
Const
  CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
  CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER) 
  CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
  if Form1.ADOConnection1.Errors.Count >0 then
  begin
    strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
    if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
    begin
      Timer2.Enabled := false;
      Timer3.Enabled := false;

      ConnStr := Form1.ADOConnection1.ConnectionString;
      tmpStrList := Common.SplitString(ConnStr,';');
      ServerIp := tmpStrList.Values['Data Source'];
      tmpStrList.Free;

      if PingServer(ServerIp) then
      begin
        Form1.ADOConnection1.Connected := false;
        Try
          Form1.ADOConnection1.Open;
          Timer2.Enabled := true;
          Timer3.Enabled := true;
        Except
        end;
      end;
    end;
  end;
end;

#8


在执行操作前,判断一下adoconnection是否联接正常。

#9


不需要吧
如果与数据库的连接断开了,你再执行OPEN或EXECSQL时,会自动连接数据库的

#10


这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。

解决方法:
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。

楼主可以试试。

#11


引用 10 楼 ZuoBaoquan 的回复:
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。 

楼主可以试试。



现是是可以了,首选会提示连接失败,我刷新会提示连接超时,再确定就连上去了,但是太耗时间了

#12


引用 11 楼 xuxugr 的回复:
引用 10 楼 ZuoBaoquan 的回复:
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。 

楼主可以试试。 




现是是可以了,首…

你像我一样把检测代码放在时钟里执行嘛,这样的话,当网络重新连通后,ADOConnection就会在后台悄悄重连了

#13


@xuxugr, @ahhjgh
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。

#14


引用 12 楼 ahhjgh 的回复:
引用 11 楼 xuxugr 的回复:
引用 10 楼 ZuoBaoquan 的回复: 
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。 

楼主可以试试…


用time事件,你是每多少时间检测一次,而且这样话是不是非常影响速度呢,耗用服务器资源呢

#15


引用 14 楼 xuxugr 的回复:
引用 12 楼 ahhjgh 的回复:
引用 11 楼 xuxugr 的回复: 
引用 10 楼 ZuoBaoquan 的回复: 
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试…

几秒检测一次,因为重连之前,我是先PING服务器的,如果不通的话,就不会去打开ADOCONNECTION,所以不会耗费服务器资源的,也基本不耗费客户端资源,整个过程不会产生检测延时,造成假死的现象

#16


路过,学习!

#17


这人问题其实挺普遍的,我们也应考虑断线是断在了数据库出问题,还是断在网络上;数据库是装在本机还是在网络服务器中;所以PING地址,查端口是一种方法(XP不装补丁?),我使用了几种方法之后,最后回归还是用SQL语句来解决问题(要求是判断断线响应时间尽量短),这里,把我的做法提出来,大家讨论一下,也给我点补充.
1.先建一个测试是否正常连接SQL的函数
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右)
var
  trylinkado:tadoquery;
begin
  result:=False;
  trylinkado:=tadoquery.Create(nil);   
  testlinkconnectstring:='Provider=SQLOLEDB.1;Password='+LogPass+';Persist Security Info=True;User ID='+LogUser+';Initial Catalog='+Database+';Data Source='+ServerName+'; connect timeout=2;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID='+ServerName+';Use Encryption for Data=False;Tag with column collation when possible=False';

  trylinkado.ConnectionString:=testlinkconnectstring;
//请务必加上connect timeout,以加快响应速度
  trylinkado.CommandTimeout:=2;
  try
    trylinkado.SQL.Add('select 1 "nettest"');
    trylinkado.Open;
    trylinkado.Close;
    Result:=True;
  except
    Result:=false;
  end;
  trylinkado.Free;
end;

2.加入一个TIMER,定时检测是否断了(调用canlink),如果断了,给用户一个提示,让他重连

3.重连后的处理
A.如果你用的是动态ADOQUERY,那么重连成功后就可以直接使用了
B.如果你的ADOQUERY跟了一个ADOConnection,我是这样做的
    try
      DM.ADOConnection1.Execute('select 1 "nettest"');
    except
      if dm.ADOConnection1.Connected=True then dm.ADOConnection1.Connected:=False;
      dm.ADOConnection1.Connected:=True;
      try
        DM.ADOConnection1.Execute('select 1 "nettest"');
      except
        ;
      end;
    end;  
C.如果你的ADOQUERY直接使用ConnectionString,好象没招(哪位有办法,也贴出告知一声吧)
4.如果你当前的进程还要控制其它进程,并通知断线和恢复,以及做相关处理,我是用广播消息来做的

#18


引用 13 楼 ZuoBaoquan 的回复:
@xuxugr, @ahhjgh 
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。

在KEEPCONNECTION=TRUE的情况下,Connected属性永远为TRUE,即使网络已断开1年也是一样,所以通过设置TIMEOUT属性的方法不可用

#19


引用 17 楼 ITlover 的回复:
这人问题其实挺普遍的,我们也应考虑断线是断在了数据库出问题,还是断在网络上;数据库是装在本机还是在网络服务器中;所以PING地址,查端口是一种方法(XP不装补丁?),我使用了几种方法之后,最后回归还是用SQL语句来解决问题(要求是判断断线响应时间尽量短),这里,把我的做法提出来,大家讨论一下,也给我点补充. 
1.先建一个测试是否正常连接SQL的函数 
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右) 
var …

这个方法比较耗费资源,并且会造成假死现象,因为:
1、当网络正常时,这种方法还是会频繁查询数据库,造成资源浪费;
2、当网络断开时,该方法会造成假死现象,首先调用canlink时,因为网络不通,会有延时等待,并且必定返回FALSE,这时又会去重连数据库,又会造成更大的延时等待。检测、重连循环进行,不断的假死,直到网络正常为止

#20


to ahhigh

  你说的是正确的,关键我们还可以在判断断了之后,可以关闭TIMER.连通后,可以重开TIMER.这样做是不会浪费资源的.最多浪费最初的判断时间5秒.

 另外,请允许我提出一点疑问:你的方法是尝试PING通服务器的IP,假如数据库安装在本机,而且是本机的数据库发生问题了呢?

  

#21


头痛,没人知道吗

#22


data module没有time事件呀,难道在进入系统的主窗体再做一个

#23


引用 18 楼 ahhjgh 的回复:
引用 13 楼 ZuoBaoquan 的回复:

@xuxugr, @ahhjgh 
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。 

在KEEPCONNECTION=TRUE的情况下,Connected属性永远为TRUE,即使网络已断开1年也是一样,所以通过设置TIMEOUT属性的方法不可用


当数据库连接成功后,如果KeepConnection=True,那碰到连接断开时Connected属性仍未True。这个时候可以在OnExecuteComplete里面可以调用Close把Connection关闭。我的意思是根据网络情况适当调整ConnectionTimeout和CommandTimeout的值,来减少超时时间。这对于采用同步连接的ADO来说,永远无法避免,使用Timer也是如此。

#24


引用 7 楼 ahhjgh 的回复:
这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考: 
procedure TForm2.Timer4Timer(Sender: TObject); 
var 
  strError:string; 
  ConnStr,ServerIp:string; 
  tmpStrList :TStringList; 
Const 
  CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位 
  CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER) 
  CONNECTFAULT_SQLSERVER…


ahhjigh

你能把form1,form2里的源代码全部发给我吗,麻烦你了,我是新手
gr.xu@yahoo.com.cn

#25


我就不相信delphi没有好的解决方法吗

#26


引用 22 楼 xuxugr 的回复:
data module没有time事件呀,难道在进入系统的主窗体再做一个

加一个timer控件.

#27


呵呵!好像没那么简单,因为在保存时比较理想的做法时保存时如果断线就会延迟10秒再执行,直到保存为止,除非退出

#28


使用IPWORKS 控件实现PINGSERVER函数
function TForm2.PingServer(ServerIp:string):boolean;
begin
  Result := True;
  ipwPing1.Timeout := 1;
  Try
    ipwPing1.PingHost(ServerIp);
  Except
    Result := False;
  end;
end;

#29


我提供的解决方案里面的timer2,timer3都是我的系统的业务逻辑,你不必关心

#1


连接代码再执行一遍

#2


搞个TIMER控件,隔段时间检查一下是否连接正常,如果断开了,再执行一次连接代码 !

#3


把里面的 KeepConnection 属性给 False 了

以后用一次连一次

#4


我试试,有点麻烦

#5


  with adoquery1 do
begin
 Connection := data1.ADOConnection1;
 Close;
SQL.Clear;
      sql.Add('select tba_ygbm.*,tba_bmbm.bmmc from tba_ygbm left join tba_bmbm on tba_ygbm.bmbm=tba_bmbm.bmbm order by ygbm');
  try
    try
     data1.ADOConnection1.Connected := false;
      data1.ADOConnection1.Connected := true;
    except
    end;
    adoquery1.Open;
  except

  end;
end;


 还是不行

#6


var
  adoq : TADOQuery;
begin
  adoq := TADOQuery.Create(nil);
  adoq.Connection := dm.ADOConn;
  adoq.Close;
  adoq.SQL.Clear;
  adoq.SQL.Add('select * from cat where 1=0');
  try
    try
      if dm.ADOConn.Connected then  
        dm.ADOConn.Connected := false;
      dm.ADOConn.Connected := true;
    except
    end;
    adoq.Open;
  except

  end;
end;



或者
  try
      while dm.ADOConn.Connected=true do
      begin
        dm.ADOConn.Connected := false;
        application.ProcessMessages;
      end;
      while dm.ADOConn.Connected=false do
      begin
        dm.ADOConn.Connected := true;
        application.ProcessMessages;
      end;
    except
    end;
都可以,不过太影响速度了,有没有简单点办法

#7


这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考:
procedure TForm2.Timer4Timer(Sender: TObject);
var
  strError:string;
  ConnStr,ServerIp:string;
  tmpStrList :TStringList;
Const
  CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
  CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER) 
  CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
  if Form1.ADOConnection1.Errors.Count >0 then
  begin
    strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
    if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
    begin
      Timer2.Enabled := false;
      Timer3.Enabled := false;

      ConnStr := Form1.ADOConnection1.ConnectionString;
      tmpStrList := Common.SplitString(ConnStr,';');
      ServerIp := tmpStrList.Values['Data Source'];
      tmpStrList.Free;

      if PingServer(ServerIp) then
      begin
        Form1.ADOConnection1.Connected := false;
        Try
          Form1.ADOConnection1.Open;
          Timer2.Enabled := true;
          Timer3.Enabled := true;
        Except
        end;
      end;
    end;
  end;
end;

#8


在执行操作前,判断一下adoconnection是否联接正常。

#9


不需要吧
如果与数据库的连接断开了,你再执行OPEN或EXECSQL时,会自动连接数据库的

#10


这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。

解决方法:
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。

楼主可以试试。

#11


引用 10 楼 ZuoBaoquan 的回复:
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。 

楼主可以试试。



现是是可以了,首选会提示连接失败,我刷新会提示连接超时,再确定就连上去了,但是太耗时间了

#12


引用 11 楼 xuxugr 的回复:
引用 10 楼 ZuoBaoquan 的回复:
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。 

楼主可以试试。 




现是是可以了,首…

你像我一样把检测代码放在时钟里执行嘛,这样的话,当网络重新连通后,ADOConnection就会在后台悄悄重连了

#13


@xuxugr, @ahhjgh
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。

#14


引用 12 楼 ahhjgh 的回复:
引用 11 楼 xuxugr 的回复:
引用 10 楼 ZuoBaoquan 的回复: 
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试自动连接。 

楼主可以试试…


用time事件,你是每多少时间检测一次,而且这样话是不是非常影响速度呢,耗用服务器资源呢

#15


引用 14 楼 xuxugr 的回复:
引用 12 楼 ahhjgh 的回复:
引用 11 楼 xuxugr 的回复: 
引用 10 楼 ZuoBaoquan 的回复: 
这个问题确实存在,主要是因为KeepConnection设为True的时候,ADOConnection会“尝试”保持数据库连接,但是碰到连接失败或网络问题的时候Connected仍未True,导致以后一直连接不上(报错)。 

解决方法: 
在OnExecuteComplete事件中判断Error是否为ahhjgh说的那些错误码,如有则显示调用Connection.Close方法,并可考虑在此处尝试…

几秒检测一次,因为重连之前,我是先PING服务器的,如果不通的话,就不会去打开ADOCONNECTION,所以不会耗费服务器资源的,也基本不耗费客户端资源,整个过程不会产生检测延时,造成假死的现象

#16


路过,学习!

#17


这人问题其实挺普遍的,我们也应考虑断线是断在了数据库出问题,还是断在网络上;数据库是装在本机还是在网络服务器中;所以PING地址,查端口是一种方法(XP不装补丁?),我使用了几种方法之后,最后回归还是用SQL语句来解决问题(要求是判断断线响应时间尽量短),这里,把我的做法提出来,大家讨论一下,也给我点补充.
1.先建一个测试是否正常连接SQL的函数
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右)
var
  trylinkado:tadoquery;
begin
  result:=False;
  trylinkado:=tadoquery.Create(nil);   
  testlinkconnectstring:='Provider=SQLOLEDB.1;Password='+LogPass+';Persist Security Info=True;User ID='+LogUser+';Initial Catalog='+Database+';Data Source='+ServerName+'; connect timeout=2;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID='+ServerName+';Use Encryption for Data=False;Tag with column collation when possible=False';

  trylinkado.ConnectionString:=testlinkconnectstring;
//请务必加上connect timeout,以加快响应速度
  trylinkado.CommandTimeout:=2;
  try
    trylinkado.SQL.Add('select 1 "nettest"');
    trylinkado.Open;
    trylinkado.Close;
    Result:=True;
  except
    Result:=false;
  end;
  trylinkado.Free;
end;

2.加入一个TIMER,定时检测是否断了(调用canlink),如果断了,给用户一个提示,让他重连

3.重连后的处理
A.如果你用的是动态ADOQUERY,那么重连成功后就可以直接使用了
B.如果你的ADOQUERY跟了一个ADOConnection,我是这样做的
    try
      DM.ADOConnection1.Execute('select 1 "nettest"');
    except
      if dm.ADOConnection1.Connected=True then dm.ADOConnection1.Connected:=False;
      dm.ADOConnection1.Connected:=True;
      try
        DM.ADOConnection1.Execute('select 1 "nettest"');
      except
        ;
      end;
    end;  
C.如果你的ADOQUERY直接使用ConnectionString,好象没招(哪位有办法,也贴出告知一声吧)
4.如果你当前的进程还要控制其它进程,并通知断线和恢复,以及做相关处理,我是用广播消息来做的

#18


引用 13 楼 ZuoBaoquan 的回复:
@xuxugr, @ahhjgh 
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。

在KEEPCONNECTION=TRUE的情况下,Connected属性永远为TRUE,即使网络已断开1年也是一样,所以通过设置TIMEOUT属性的方法不可用

#19


引用 17 楼 ITlover 的回复:
这人问题其实挺普遍的,我们也应考虑断线是断在了数据库出问题,还是断在网络上;数据库是装在本机还是在网络服务器中;所以PING地址,查端口是一种方法(XP不装补丁?),我使用了几种方法之后,最后回归还是用SQL语句来解决问题(要求是判断断线响应时间尽量短),这里,把我的做法提出来,大家讨论一下,也给我点补充. 
1.先建一个测试是否正常连接SQL的函数 
function canlink:boolean;//(这种方法,如果断了,响应时间大概是5秒左右) 
var …

这个方法比较耗费资源,并且会造成假死现象,因为:
1、当网络正常时,这种方法还是会频繁查询数据库,造成资源浪费;
2、当网络断开时,该方法会造成假死现象,首先调用canlink时,因为网络不通,会有延时等待,并且必定返回FALSE,这时又会去重连数据库,又会造成更大的延时等待。检测、重连循环进行,不断的假死,直到网络正常为止

#20


to ahhigh

  你说的是正确的,关键我们还可以在判断断了之后,可以关闭TIMER.连通后,可以重开TIMER.这样做是不会浪费资源的.最多浪费最初的判断时间5秒.

 另外,请允许我提出一点疑问:你的方法是尝试PING通服务器的IP,假如数据库安装在本机,而且是本机的数据库发生问题了呢?

  

#21


头痛,没人知道吗

#22


data module没有time事件呀,难道在进入系统的主窗体再做一个

#23


引用 18 楼 ahhjgh 的回复:
引用 13 楼 ZuoBaoquan 的回复:

@xuxugr, @ahhjgh 
只要不采用异步连接/执行,ADO超时的情况就无法避免。你可以根据网络情况适当调整ConnectionTimeout和CommandTimeout的值。 

在KEEPCONNECTION=TRUE的情况下,Connected属性永远为TRUE,即使网络已断开1年也是一样,所以通过设置TIMEOUT属性的方法不可用


当数据库连接成功后,如果KeepConnection=True,那碰到连接断开时Connected属性仍未True。这个时候可以在OnExecuteComplete里面可以调用Close把Connection关闭。我的意思是根据网络情况适当调整ConnectionTimeout和CommandTimeout的值,来减少超时时间。这对于采用同步连接的ADO来说,永远无法避免,使用Timer也是如此。

#24


引用 7 楼 ahhjgh 的回复:
这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考: 
procedure TForm2.Timer4Timer(Sender: TObject); 
var 
  strError:string; 
  ConnStr,ServerIp:string; 
  tmpStrList :TStringList; 
Const 
  CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位 
  CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER) 
  CONNECTFAULT_SQLSERVER…


ahhjigh

你能把form1,form2里的源代码全部发给我吗,麻烦你了,我是新手
gr.xu@yahoo.com.cn

#25


我就不相信delphi没有好的解决方法吗

#26


引用 22 楼 xuxugr 的回复:
data module没有time事件呀,难道在进入系统的主窗体再做一个

加一个timer控件.

#27


呵呵!好像没那么简单,因为在保存时比较理想的做法时保存时如果断线就会延迟10秒再执行,直到保存为止,除非退出

#28


使用IPWORKS 控件实现PINGSERVER函数
function TForm2.PingServer(ServerIp:string):boolean;
begin
  Result := True;
  ipwPing1.Timeout := 1;
  Try
    ipwPing1.PingHost(ServerIp);
  Except
    Result := False;
  end;
end;

#29


我提供的解决方案里面的timer2,timer3都是我的系统的业务逻辑,你不必关心