2011-09-19 3 views
2

우리는 폼의 hundreads에 ADO 구성 요소 (TADODataset, TADOStoredPRoc, TADOCommand ...)가 많이 포함 된 HUGE Delphi 2005 응용 프로그램을 보유하고 있습니다. 그들 모두는 단일 TAD 연결에 연결되어 있습니다.Delphi : 전체적으로 ADO 명령 타임 아웃을 변경하십시오.

대부분의 구성 요소는 CommandTimeout 속성이 기본값 (30 초)으로 설정되어 있지만 일부는 5 분 (300 초)으로 설정되고 일부는 결코 제한 시간 (0 초)으로 설정되지 않습니다.

응용 프로그램과 관련된 모든 ADO 구성 요소에 대해이 설정을 전체적으로 변경할 수 있기를 바랍니다. 런타임시 프로그래밍 방식으로 수행하여 설치가 필요할 경우 시간 제한을 조정할 수 있습니다.

ADO 구성 요소를 만들거나 첨부 할 때 커맨드 타임 아웃을 조정하거나 구성 요소 자체에 코드를 삽입 할 때 전역 이벤트를 찾을 수 있기를 기대했지만 비어 있습니다.

모든 컴포넌트를 검색/대체해야하기 때문에 디 센트먼트를 만들고 싶지 않습니다. 정규 ADO 컴포넌트 대신 자손을 사용하는 것을 잊어 버리면 시간 제한은 나머지 애플리케이션을 따르지 않을 것입니다. .

아무도 우리가이 작업을 수행 할 수있는 방법을 알고 있습니까?

답변

3

모든 ADO 구성 요소가 양식에 배치되면 Screen.Forms 및 Screen.FormCount 속성을 사용하여 모든 양식을 반복 할 수 있습니다. 각 양식에 대해 해당 ComponentCount/Components 특성을 반복하고 TADOCommand, TADODataSet, TADOQuery, TADOStoredProc 및 TADOTable을 점검하십시오. 그런 다음 원하는 시간 제한을 설정할 수 있습니다. 물론 양식을 동적으로 작성하는 경우이를 별도로 고려해야합니다.

다음 코드가 도움이 될 수 있습니다.

procedure SetADOTimeout(ATimeout: Integer); 
var 
    cmp: TComponent; 
    frm: TForm; 
    I: Integer; 
    J: Integer; 
begin 
    for I := 0 to Screen.FormCount - 1 do begin 
    frm := Screen.Forms[I]; 
    for J := 0 to frm.ComponentCount - 1 do begin 
     cmp := frm.Components[J]; 
     if cmp is TADOCommand then 
     TADOCommand(cmp).CommandTimeout := ATimeout 
     else if cmp is TADODataSet then 
     TADODataSet(cmp).CommandTimeout := ATimeout 
     else if cmp is TADOQuery then 
     TADOQuery(cmp).CommandTimeout := ATimeout 
     else if cmp is TADOStoredProc then 
     TADOStoredProc(cmp).CommandTimeout := ATimeout 
     else if cmp is TADOTable then 
     TADOTable(cmp).CommandTimeout := ATimeout; 
    end; 
    end; 
end; 
0

문서에 따르면, 당신은 CommandCountCommandsTADOConnection에 연결된 모든 열린 구성 요소를 찾는 데 사용할 수 있습니다.

문제는 동적으로 생성 된 양식 일 가능성이 큽니다. 양식을 만들 때 연결하기 위해 "무언가"를 찾고 해당 양식에서 ADO 구성 요소를 확인해야합니다.

양식이 사용자 정의 양식 클래스에서 파생 된 경우 양식의 constructor 또는 OnCreate 이벤트에서이 양식을 작성할 수 있습니다.

그렇지 않은 경우 TApplicationEvents을보고 TApplication's OnIdle 이벤트를 사용할 수 있습니다.

0

CommandTimeout이 TCustomADODataset 클래스에 추가되었으므로 각 폼/데이터 모듈을 반복하고 TCustomADODataset 및 해당 자손 (ADODataset, ADOTable, ADOQuery)을 찾은 다음 속성을 설정할 수 있습니다.

procedure SetADOCommandTimeOut(aTimeOut: integer); 
var 
    i, j: integer; 
begin 
    for i:= 0 to Screen.FormCount-1 do 
    begin 
    for j:= 0 to Forms[i].ComponentCount-1 do 
     if Forms[i].Components[j] is TCustomADODataset then 
     TCustomADODataset1(Forms[i].Components[j]).CommandTimeOut:= aTimeOut; 
    end; 

    for i:= 0 to Screen.DataModuleCount-1 do 
    begin 
    for j:= 0 to Datamodules[i].ComponentCount-1 do 
     if Datamodules[i].Components[j] is TCustomADODataset then 
     TCustomADODataset1(Datamodules[i].Components[j]).CommandTimeOut:= aTimeOut; 
    end; 
end; 

참고 : TCustomADODataset1 정확히 TCustomADODataset입니다 만 그것은 게시 된 CommandTimeout이 속성했습니다

TCustomADODataset1 = class(TCustomADODataset) 
published 
    property CommandTimeOut; 
end; 

그러나 그것은 단지 이미 생성 된 양식/datamodules에 적용합니다. 양식/데이터 모듈을 동적으로 작성하는 경우 새 양식/데이터 모듈을 작성할 때마다 양식/데이터 모듈을 적용해야합니다. 한 가지 방법은 폼의/datamodule 생성을 확인하기 위해 Mainform의 override Notification을 사용하는 것입니다.하지만 생성 시간에 모든 구성 요소가 아직 생성되지 않았으므로 약간 까다 롭습니다. 당신은 데이터 모듈 계층 구조를 만들

Procedure TMainForm.Notification(AComponent: TComponent; Operation: TOperation); 
begin 
    inherited; 
    if (Operation = opInsert) and (
    ((AComponent is TForm) and not (aComponent is TMainForm)) // exclude MainForm 
    or (AComponent is TDataModule) 
    ) then 
    begin 
    Timer1.Interval:= 2000; // 2 seconds ? 
    Timer1.Enabled:= True; 
    end; 
end; 

Procedure TMainForm.Timer1Timer(Sender: TObject); 
begin 
    Timer1.Enabled:= False; 
    SetADOCommandTimeOut(MyTimeOut); 
end; 
+0

보호 속성은 대상 속성이있는 클래스와 같은 단위에있는 클래스에서 액세스 할 수 있습니다. 즉, 'TCustomADODataset1' 선언을 속성을 참조하는 코드와 동일한 단위로 유지하는 한'CommandTimeout' 속성을 게시 할 필요가 없습니다. 그래서, 당신의'TCustomADODataset1'은 간단히 다음과 같이 보일 수 있습니다 :'TCustomADODataset1 = class (TCustomADODataset) end;'. 이 메소드는'TCustomADODataset'의 자손이 아닌'TADOCommand'를 고려하지 않습니다. –

+0

와우, 이런 일을 단순화하기 위해이 동작을 적용 할 생각은 전혀 없었습니다. 감사합니다 Andriy. –

0

-에 의해 당신은 타이머 (단지 아이디어를 보여 내가 더 우아한 방법을 알고하지 않습니다)를 사용하여 잠시 동안 지연을 속여? 그렇다면 축복 사의 양식 (모든 다른 데이터 모듈이 상속받는)에 대한 Uwe의 대답과 같은 코드를 사용할 수 있습니다.

1

모든 아르헨티나 해결책에 인사드립니다!

그냥 당신이 가지고있는 TADOConnection에 대한 OnWillExecute 이벤트 핸들러를 정의 및 쓰기 코드를 다음

type 
    TCustomADODataSetAccess = class(TCustomADODataSet); 

procedure TYourDataModule.ADOConnectionWillExecute(...); 
var 
    i: Integer; 
begin 
    for i := 0 to ADOConnection.DataSetCount - 1 do 
    TCustomADODataSetAccess(ADOConnection.DataSets[i]).CommandTimeout := Connection.CommandTimeout; 
end; 

이것은 당신의 ADO 연결을 사용하는 모든 쿼리/테이블/저장 프로 시저에 대한 명령 제한 시간을 설정합니다.

관련 문제