TADOConnection不具备断网重连的能力,弄得程序在网络比较糟糕的时候表现不佳,虽然断网不是程序的问题,但客户希望在网络恢复正常的时候程序还可以继续使用。
在网上找了一下,很多人都面临同样的问题,但解决方案大都是加一个Timer,然后不断检查网络,如果网络不正常就重新连接网络,说实话,这个方案真不怎么样,不但增加了系统开销,而且并不实时,不能保证并发性。
我自己写了一个,高效的解决了这一问题,和他们的做法不同,我是用继承的方式实现的断网后重连功能,
我的做法是继承TADOConnection,改进一下连接的方法,有异常发生就关掉Connection。这样就实现了断网重连,其实这也不算是断网重连,应该是断网后自动关闭连接。
代码如下
{----------------------------------------------------------------------------- Unit Name: uNewADODB Author: 52ij Date: 2015-01-29 Purpose: 继承自TADOConnection,提供了连接失败后自动关闭连接的功能,以此保证网络断开后又恢复正常后能自动重连 History: -----------------------------------------------------------------------------} unit uAessADODB; interface uses classes, sysUtils, windows, DB, ADODB; type TNewADOConnection = class; TNewADOCommand = class(TADOCommand) private function getConnection: TNewADOConnection; procedure setConnection(const Value: TNewADOConnection); public function Execute(var RecordsAffected: Integer; const Parameters: OleVariant): _Recordset; virtual; published property Connection: TNewADOConnection read getConnection write setConnection; end; TNewADOConnection = class(TADOConnection) private fOnConnectError: TNotifyEvent; protected procedure DoConnect; override; published property OnConnectError : TNotifyEvent read fOnConnectError write fOnConnectError;//连接失败后的事件,可以在这里写点日志什么的,日后程序出了问题,可以拿着日志批评客户说你们网络太糟糕了,老是断网。 property Connected stored false;//不保存Connected属性,这个属性很讨厌,干脆不保存。 end; procedure Register; implementation procedure Register; begin RegisterComponents('ado',[TNewADOConnection, TNewADOCommand]); end; { TNewADOConnection } procedure TNewADOConnection.DoConnect; begin try inherited; except on e:Exception do begin Close; if assigned(fOnConnectError) then fOnConnectError(Self); raise end;//e end;//except end; { TNewADOCommand } function TNewADOCommand.Execute(var RecordsAffected: Integer; const Parameters: OleVariant): _Recordset; begin try Result := inherited Execute(RecordsAffected, Parameters); except on e:Exception do begin if assigned(Connection) and (Connection is TNewADOConnection) then begin TNewADOConnection(Connection).Close; if assigned(TNewADOConnection(Connection).OnConnectError) then TNewADOConnection(Connection).OnConnectError(Connection); end; raise; end;//e end;//except end; function TNewADOCommand.getConnection: TNewADOConnection; begin Result := inherited Connection as TNewADOConnection; end; procedure TNewADOCommand.setConnection(const Value: TNewADOConnection); begin inherited Connection := Value; end; end.
注册之后在ado页会多出两个控件,TNewADOCommand,TNewADOConnection,用法很简单,只要用TNewADOConnection替换掉TADOConnection,
经过测试,替换了连接器之后TADODataSet具备了断网自动重连的功能,但TADOCommand不具备此能力,因此本人又改了一个TNewADOCommand,估计TADOQuery也没问题,别的ADO组件本人没有用到,因此也没有测试。
