Q&A

  • 쓰레드 사용중 문제
메인화면에서 조회버튼을 클릭하면
DAEJEON_CITY_THREAD; 쓰레드를 호출하고

procedure는 다른 pas에 존재한다.
호출된 procedure 내용을 다음과 같다
procedure DAEJEON_CITY_THREAD;
var
  FDAEJEON_CITY_THREAD : TDAEJEON_CITY_THREAD;
begin
  FDAEJEON_CITY_THREAD := TDAEJEON_CITY_THREAD.Create(True);
  FDAEJEON_CITY_THREAD.Priority := tpNormal;

  try
    FDAEJEON_CITY_THREAD.Resume;
    Sleep(1);
  except
    on E: Exception do
    begin
      FDAEJEON_CITY_THREAD.Free;
      ShowMessage('오류내용:'+E.Message);
    end;
  end;
end;

//===========================쓰레드 내용
unit NIS_DAEJEON_CITY_THREAD;

interface

uses
  Classes, DB, MemDS, DBAccess, Ora, SysUtils, QDialogs, IniFiles, QForms;

type
  TDAEJEON_CITY_THREAD = class(TThread)
  private
    { Private declarations }
    SVRLIST               : TIniFile;
    DaeJeon_City_Ora_Ses  : TOraSession;
    DaeJeon_City_qry      : TOraQuery;    
  protected
    procedure Execute; override;
    procedure ThreadsDone(Sender: TObject);
  end;

implementation

{ Important: Methods and properties of objects in VCL or CLX can only be used
  in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TDaeJeonThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ TDAEJEON_CITY_THREAD }

uses NIS_STATE;

var
  DaeJeon_City_State : Array [0..4] of String;

procedure TDAEJEON_CITY_THREAD.Execute;
var
  Ls_Username : String;
  Ls_Password : String;
  Ls_Server   : String;
begin
  { Place thread code here }
  FreeOnTerminate := True;  
  OnTerminate     := ThreadsDone;

  SVRLIST := TIniFile.Create(ExtractFilePath(Application.ExeName)+'대전.INI');
  Ls_Username := SVRLIST.ReadString('SERVER1', 'USERNAME', '');
  Ls_Password := SVRLIST.ReadString('SERVER1', 'PASSWORD', '');
  Ls_Server   := SVRLIST.ReadString('SERVER1', 'SERVER', '');
  SVRLIST.Free;

  DaeJeon_City_Ora_Ses                        := TOraSession.Create(DaeJeon_City_Ora_Ses);
  DaeJeon_City_Ora_Ses.Name                   := 'DaeJeon_City_Ora_Sess';
  DaeJeon_City_Ora_Ses.ConnectPrompt          := False;
  DaeJeon_City_Ora_Ses.Username               := Ls_Username;
  DaeJeon_City_Ora_Ses.Password               := Ls_Password;
  DaeJeon_City_Ora_Ses.Server                 := Ls_Server;
  DaeJeon_City_Ora_Ses.Options.Net            := True;
  DaeJeon_City_Ora_Ses.Options.EnableIntegers := True;
  DaeJeon_City_Ora_Ses.Options.NeverConnect   := False;
  DaeJeon_City_Ora_Ses.Options.UseOCI7        := False;
  DaeJeon_City_Ora_Ses.ThreadSafety           := True;

  try
    DaeJeon_City_Ora_Ses.Connect;
  except
    // 연결되지 않으므로 오류 내용을 찍는다
    // 해당서버 단체명을 뿌려준다
    DaeJeon_City_State[00] := '대전 본청 - 자료없슴';
    DaeJeon_City_State[01] := '0';
    DaeJeon_City_State[02] := '0';
    DaeJeon_City_State[03] := '0';
    DaeJeon_City_State[04] := '0';
  end;
end;

procedure TDAEJEON_CITY_THREAD.ThreadsDone(Sender: TObject);
  function GF_Chrcut(GPs_v:string ; GPs_xch:string): string;
  begin
    while pos(GPs_xch,GPs_V) > 0 do
    begin
      delete(GPs_V,pos(GPs_xch,GPs_v),1);
    end;
    if GPs_V = '' then Result := '0'
    else Result := GPs_V;
  end;

  function GF_Chrcut_I(GPs_v:string ; GPs_xch:string): Integer;
  begin
    while pos(GPs_xch,GPs_V) > 0 do
    begin
      delete(GPs_V,pos(GPs_xch,GPs_v),1);
    end;
    if GPs_V = '' then Result := 0
    else Result := StrToInt(GPs_V);
  end;
var
  j        : Integer;
  RowNo    : Integer;
  Svr_Row  : String;
  CityName : String;
begin
  DaeJeon_City_qry := TOraQuery.Create(DaeJeon_City_qry);
  DaeJeon_City_qry.Session := DaeJeon_City_Ora_Ses;

  with DaeJeon_City_qry do
  begin
    Close;
    Sql.Clear;
    Sql.Text := ' SELECT COUNT(1) CNT, ''부'' GUBUN '
              + '   FROM RISTNLVBOOK '
              + '  WHERE LVY_STT_GBN = ''01'' '  //부과
              + '    AND LVY_YMD <= '+QuotedStr(FormatDateTime('YYYYMMDD', wf_State.edt_Acc_Year.Date))
              + ' UNION '
              + ' SELECT COUNT(1) CNT, ''체'' GUBUN '
              + '   FROM RISTNLVBOOK '
              + '  WHERE LVY_STT_GBN = ''02'' '  //체납
              + '    AND LVY_YMD <= '+QuotedStr(FormatDateTime('YYYYMMDD', wf_State.edt_Acc_Year.Date));
    Open;
  end;

  for j := 0 to DaeJeon_City_qry.RecordCount-1 do
  begin
    if DaeJeon_City_qry.FieldByName('GUBUN').AsString = '부' then
    begin
      DaeJeon_City_State[03] := FormatFloat('#,##0',DaeJeon_City_qry.FieldByName('CNT').AsFloat);
      DaeJeon_City_State[02] := FormatFloat('#,##0',StrToFloat(GF_Chrcut(DaeJeon_City_State[02],','))+
                                                    StrToFloat(GF_Chrcut(DaeJeon_City_State[03],',')));
    end
    else
    if DaeJeon_City_qry.FieldByName('GUBUN').AsString = '체' then
    begin
      DaeJeon_City_State[04] := FormatFloat('#,##0',DaeJeon_City_qry.FieldByName('CNT').AsFloat);
      DaeJeon_City_State[02] := FormatFloat('#,##0',StrToFloat(GF_Chrcut(DaeJeon_City_State[02],','))+
                                                    StrToFloat(GF_Chrcut(DaeJeon_City_State[04],',')));
    end;

    DaeJeon_City_qry.Next;
  end;

  RowNo    := 0;
  if wf_State.Chk_Gbn then
  begin // 전체를 선택했을경우
    Svr_Row  := '';
    SVRLIST  := TIniFile.Create(ExtractFilePath(Application.ExeName)+'대전.INI');
    Svr_Row  := SVRLIST.ReadString('SERVER_CODE', 'SERVER1', '');
    SVRLIST.Free;

    SVRLIST  := TIniFile.Create(ExtractFilePath(Application.ExeName)+'SVRLIST.INI');
    RowNo    := SVRLIST.ReadInteger('SERVER_ROW', Svr_Row, 0);
    SVRLIST.Free;
  end
  else
  begin
    SVRLIST  := TIniFile.Create(ExtractFilePath(Application.ExeName)+'대전.INI');
    RowNo    := SVRLIST.ReadInteger('SEVER_NO', 'SERVER1', 0);
    SVRLIST.Free;
  end;

  SVRLIST  := TIniFile.Create(ExtractFilePath(Application.ExeName)+'대전.INI');
  CityName := SVRLIST.ReadString('SERVER_LIST', 'SERVER1', '');
  SVRLIST.Free;

  // 실과수
  DaeJeon_City_qry.FetchAll := True;
  with DaeJeon_City_qry do
  begin
    Close;
    Sql.Clear;
    Sql.Text := 'SELECT DISTINCT DEP_CODE '
              + '  FROM RISTNLVBOOK ';
    Open;
  end;
  DaeJeon_City_State[01] := FormatFloat('#,##0',DaeJeon_City_qry.RecordCount);

  wf_State.gdrd_Main.Cells[00, RowNo] := CityName;
  wf_State.gdrd_Main.Cells[01, RowNo] := DaeJeon_City_State[01];
  wf_State.gdrd_Main.Cells[02, RowNo] := DaeJeon_City_State[02];
  wf_State.gdrd_Main.Cells[03, RowNo] := DaeJeon_City_State[03];
  wf_State.gdrd_Main.Cells[04, RowNo] := DaeJeon_City_State[04];

  wf_State.gdrd_Main.Cells[01, 1] := FormatFloat('#,##0',GF_Chrcut_I(DaeJeon_City_State[01],',')+GF_Chrcut_I(wf_State.gdrd_Main.Cells[01, 1],','));
  wf_State.gdrd_Main.Cells[02, 1] := FormatFloat('#,##0',GF_Chrcut_I(DaeJeon_City_State[02],',')+GF_Chrcut_I(wf_State.gdrd_Main.Cells[02, 1],','));
  wf_State.gdrd_Main.Cells[03, 1] := FormatFloat('#,##0',GF_Chrcut_I(DaeJeon_City_State[03],',')+GF_Chrcut_I(wf_State.gdrd_Main.Cells[03, 1],','));
  wf_State.gdrd_Main.Cells[04, 1] := FormatFloat('#,##0',GF_Chrcut_I(DaeJeon_City_State[04],',')+GF_Chrcut_I(wf_State.gdrd_Main.Cells[04, 1],','));

  wf_State.gdrd_Main.Refresh;
  DaeJeon_City_Ora_Ses.Free;
  DaeJeon_City_qry.Free;
end;

end.

이런한 내용의 pas를 지역별로 여러개 생성해서
메인에서 조회를 클릭하면 여러 지역 쓰레드를
계속적으로 호출한다

어쩔때는 정상적으로 되다가 어쩔때는
다음과 같은 에러가 나오는데 에러 내용을 다음과 같다.
"OCI_INVALID_HANDLE" 이것이 한번 나오기 시작하면
계속해서 문제가 생겨서 실행되지 않는다

즐거운 하루 되세요
2  COMMENTS
  • Profile
    김경록 2003.06.22 00:29
    Thread의 내용중에
    Excute에 직접 Coding은 되도록 자제하시구여
    특정 Procedure나 Function을 작성하시구..
    그곳에서 기능을 모두 Coding하시구여
    Synchronize 을 이용해서 해당 Procedure를 호출해 주세요..
    그렇게 하지 않는다면,
    어떤 Thread가 다른 Thread에 대한 참조를 할때
    Class문제가 발생할 소지가 있어
    님의 에러가 발생할수가 있습니다..
    Delphi는 Class가 있지만, 똑같은 Class는
    Title로서 구분한다는거 아시져?
    그런 비슷한원리로 인해서.. Handle에러가 발생할 수 있습니다.
    뭐.. 간단한 예를 들어서 그렇지만..
    깊이들어가면, 다른 요소도 있겠져..
    어쨌든..
    Synchronize를 이용하시면, Error가 발생치 않을겁니다..
    그럼..


  • Profile
    서영택 2003.06.28 01:04
    내용무
    • 아폴론
    • 2003.06.23 20:56
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 바보감자
      2003.06.23 21:19
      안녕하세요 언제나 초보 바보감자입니다.. 채크 박스 올려놓고 이걸 테스트 해보시면..될듯 싶어요.. TCh...
    • 박찬희
    • 2003.06.23 20:34
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 박서규
      2003.06.23 22:51
      가장 쉬운방법은 메시지를 보낼때 내부적으로 아이디나 특정 유니크한 값을 보내서 그 쓰데드를 구분하시고...
    • 박찬희
      2003.06.23 23:32
    • KDDG_ZZOM
      2003.06.23 20:34
      쿼리문에서 오류가 있는것같네요... 오픈하기전에 query.sql.text등으로 완성된 쿼리를 구해서 직접실행...
    • 바보감자
      2003.06.23 20:32
      안녕하세요 언제나 초보 바보감자입니다. SQL 문이 잘못된듯싶습니다. 한번 SQL문을 올려보심이..좋을듯 ...
    • 정현석
    • 2003.06.23 19:54
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 나그네
      2003.06.24 00:30
      bindcltqr70.bpl 을 component->install package에서 추가 하세요..
    • 몽중인
    • 2003.06.23 18:14
    • 3 COMMENTS
    • /
    • 0 LIKES
    • KDDG_BaSTaD
      2003.06.23 23:19
      ==> 안녕하세요 전병호입니다. (_ _) 저도 TIdFTPServer를 이용해서 옆튀퓌써버를 맹길어 보긴했는데...
    • 몽중인
      2003.06.23 23:42
      답변 감사합니다. 오늘 집에 가시면 자료 좀 올려주시면 감사하겠습니다. 제가 스킬이 높지 못해서 (^^...
    • KDDG_BaSTaD
      2003.06.24 11:35
      ==> 잠자려고하니 문득 생각나서 올립니다. ^^;; 데모한번 만들어볼라다만.. TIdFTPServer 예제입니다...
    • 김정은
    • 2003.06.22 07:09
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 이광철
      2003.07.05 06:17
      procedure TForm1.Button1Click(Sender: TObject); var    F: TextFile; begin ...
    • 남기섭
    • 2003.06.22 06:17
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 바보감자
      2003.06.23 21:49
      안녕하세요 언제나 초보 바보감자입니다.. 쿼리나 테이블은 자기가 연결된 녀석들의 정보를 가지고 있는겁...
    • 송정철
    • 2003.06.22 04:42
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 바보감자
      2003.06.23 20:29
      안녕하세요 언제나 초보 바보감자입니다.. 폼을 캡쳐하신후에. 퀵리포트에 이미지 콤포 하나 올려서 영역 ...
    • 이용주
    • 2003.06.22 02:01
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 신연근
      2003.06.23 19:08
      Form의 이벤트에 보면 OnClick 에 해당하는 이미지 생성하면 되지 않을까여? 그럼..즐프..
    • 이병언
    • 2003.06.22 01:55
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 바보감자
      2003.06.23 21:13
      안능하세요 언제나 초보 바보감자입니다. SetWindowPos( wnd, 0, 0, 0, clientwidth, clientheight, &nbs...
    • 이진성
    • 2003.06.22 00:11
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.06.22 01:11
      안녕하세요. 최용일입니다. 아마도 ValueA < ValueB 하고 ValueA mod ValueB > 0를 or 연산하실려...
    • 이진성
      2003.06.22 01:21
      최용일님.. 좋은하루되세요.. 감사합니다.. ^^
    • 손광현
      2003.06.24 22:03
      KeyDown 이벤트에 코딩하세요.. //Alt + F4 무시 procedure TForm1.FormKeyDown(Sender: TObject; var ...
    • 장재영
    • 2003.06.21 20:41
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 하리수
    • 2003.06.21 18:06
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 수훈
    • 2003.06.21 08:17
    • 3 COMMENTS
    • /
    • 0 LIKES
    • ^ㅡ^
      2003.06.21 19:59
      초보가 한 말씀 드리겠습니다. 이미지를 저장하시려면  그래픽파입이 있을꺼구요 경로를 저장...
    • 수훈
      2003.06.22 00:11
      여기에서 봤던 방법인데요 확실히 애러 없이 돌아가는데 이미지가 저장 안되네요. 크.!~~ 필드 타입을...
    • ^ㅡ^
      2003.06.22 01:44
      //답변이 되었으면 하네요 초보가... //어차피 이미지위에 그림을 올릴실꺼니까 이렇게 하시면 될꺼 ...
    • ^ㅡ^
      2003.06.21 20:05
      그러시면 뒤쪽 내용을 안 보여 주시면 되지 않나요?? 필드를 빼시면 될꺼 같은데요.. 그러면 가로 스크롤...
    • 박상철
    • 2003.06.21 06:22
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2003.06.21 08:04
      안녕하세요. 최용일입니다. 이벤트로는 할 수 없구요... 윈도우메세지를 이용하시면 됩니다... 크기...
    • 서영택
    • 2003.06.21 03:34
    • 2 COMMENTS
    • /
    • 1 LIKES
    • 김경록
      2003.06.22 00:29
      Thread의 내용중에 Excute에 직접 Coding은 되도록 자제하시구여 특정 Procedure나 Function을 작성하시...
    • 서영택
      2003.06.28 01:04
      내용무
    • 박상기
      2003.06.21 04:33
      VRFY가 안되는 것은 그쪽 서버에서 그렇게 해 놓았기 때문입니다. Rcpt to를 먹여서 넘어오는 내용을 참고...
    • 유창원
      2003.06.21 04:41
      정녕 서버에서 설정을 한다는 말씀이십니까? 그럼 VRFY는 사용을 할 수가 없겠네요? RCPT 커맨드로...
    • 박상기
      2003.06.21 23:50
      네..그렇습니다. RCPT TO로 확인하셔야 합니다.