Q&A

  • Thread에서요 IdSMTP컴포넌트를 사용할 수 없나요?
안녕하세요?

다름이 아니오라 Thread에서 IdSMTP를 사용하면 Access Violation이 발생합니다. 원래 안되는 건가요? 아니면 뭐가 잘못된건가요? 도와 주세요^^

=================================
호출하는 부분
=================================
mailer := TMailSender.Create(errorlists);
mailer.Suspend;



====================================
Thread
====================================
unit MailSender;


interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, comctrls,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdMessageClient, IdSMTP, StdCtrls, ExtCtrls, IdMessage, IdEMailAddress;


type
  TMailSender = class(TThread)

private
        ErrorList : TStringList;
 protected
        procedure Execute; override;
  public
        constructor Create(errors : TStringList);
        destructor Destroy; override;

  end;

implementation

uses Main, SAUtil;

//생성자
constructor TMailSender.Create(errors : TStringList);
begin
        ErrorList := errors;
        inherited Create(true);
        FreeOnTerminate := true;
end;

//소멸자
destructor TMailSender.Destroy;
begin
// some free ping component;
inherited;
end;

procedure TMailSender.Execute;
var
        host : String;
        port : Integer;
        sender : String;
        id : String;
        passwd : String;
        auth : Boolean;
        rcvs : TStringList;

        IdSMTP1 : TIdSMTP;
        msg : TIdMessage;
        emaillist : TIdEMailAddressList;
        from : TIdEMailAddressItem;
        textPart: TIdText;
        currentTime : String;

        i : Integer;
        erroridx : Integer;
        rcvidx : Integer;
begin
        host := SAUtil.smtphost;
        port := SAUtil.smtpport;
        sender := SAUtil.from;
        id := SAUtil.userid;
        passwd := SAUtil.smtppassword;
        auth := SAUtil.auth;
        rcvs.CommaText := SAUtil.emailTarget;

{IdSMTP1을 참조만 하면 AccessViolation이 생깁니다.}        
        //Indy SMTP 컴포넌트
        IdSMTP1 := TIdSMTP.Create(nil);

        //HELO픞 사용한다.
        IdSMTP1.UseEhlo := true;
        IdSMTP1.HeloName := id;
        //SMTP Host, Port
        IdSMTP1.Host := host;
        IdSMTP1.Port := port;

        //메일 메세지
        msg := TIdMessage.Create(nil);
        msg.Clear;
        msg.ContentType := 'Multipart/Alternative';

        {
        // add a plain text message part
        textPart:=TIdText.Create(msg.MessageParts,nil);
        textPart.ContentType:='text/plain';
        textPart.Body := errorlist;
        }

        // 보내는 문자열 HTML message
        textPart:= TIdText.Create(msg.MessageParts, nil);
        textPart.ContentType := 'text/html';
        for erroridx:=0 to errorlist.Count-1 do begin
                textPart.Body.add(errorlist[erroridx] + '<br>');
        end;
        msg.Body := textPart.Body;
        
        //보내는 사람
        from := TIdEmailAddressItem.Create(nil);
        from.Name := id;
        from.Address := sender;

        //Auth Information
        if auth then begin
                IdSMTP1.AuthenticationType := atLogin;
                IdSMTP1.UserName := id;
                IdSMTP1.Password := passwd;
        end
        else begin
                IdSMTP1.AuthenticationType := atNone;
        end;

        //메일 메세지의 항목을 채운다.
        msg.Subject := 'ServiceAlive Monitoring Result - Error';
        msg.From := from;

        try
                //받는사람
                for rcvidx:=0 to rcvs.Count-1 do begin
                        msg.Recipients.clear;
                        //for i:=0 to rcvs.Count-1 do begin
                        msg.Recipients.Add.Address := rcvs.Strings[rcvidx];
                        //end;

                        try
                                currentTime := FormatDateTime('yyyy"/"mm"/"dd hh:mm:ss', StrToDateTime(DateTimeToStr(Now)));
                                IdSMTP1.Connect;
                                IdSMTP1.Send(msg);
                                Form1.AddEventLog(0, currentTime, '메일 전송 성공[' + rcvs.Strings[rcvidx] + ']');
                                IdSMTP1.Disconnect;
                        except
                                on e: Exception do begin
                                        Form1.AddEventLog(2, currentTime, '메일 전송중에 에러발생[' + e.message + ']');
                                        IdSMTP1.Disconnect;
                                        continue;
                                end;
                        end;

                end;    //End For Statement
        finally
                IdSMTP1.Destroy;
        end;
end;
3  COMMENTS
  • Profile
    KDDG_BaSTaD 2003.02.15 01:22
    ==> 제가 예전에 만들어 놓은.. 멀티쓰레드로 왕창 메일 보내는 플그램입니다. 쓰레드 3000개 까지 올리고 쓰레드당 50개씩에 쓰레드 딜레이는 몇 밀리 정도 주시고.. ^^; D6 에 Indy 9.0.0 이던가? ㅡ_ㅡ.. 그당시
    Indy버전이 정확히 생각은 않되는데 함 해보세요 ^^; 소스만 보시믄 금방 이해되실겁니다...




  • Profile
    유창원 2003.02.15 01:43
    올려주신 자료는 잘 사용하겠습니다.
    Indy Thread는 아직 써본적이 없어서 잘은 모르겠지만.....
    그리고 Indy의 Thread는 사용할만한지요?

    다시한번 자료 감사합니다.
  • Profile
    KDDG_BaSTaD 2003.02.15 01:59


    ==> TIdThread는 TThread를 상속받아 자체적으로 편의성을 높인것이지요.. 필요에 따라 사용하시면 됩니다. Indy 자체 내부적으로는 물론 TIdThread를 사용하죠 ^^;  TIdThread를 사용하시려면 우선 TIdThread 내부 코드를 이해하신 후 사용하시기를 추천합니다. 물론 어떤것도 마찬가지만 ^^;;

    Indy 자체는 훌륭한 패키지입니다.. 블럭의 장점을 최대한 살려 프로그래밍하기가 참 쉽죠.. 가끔 이런 블럭이 문제라 쓰레드도 사용하지만 ^^;;

      그리고, Thread Pool은 개념상 어려워 보이지만, 실은 그렇지도 않습니다. Indy에선 컴포넌트로도 제공하기때문에 쓰레드 관리도 쉽죠 ^^;; Thread간 통신이 없다면, 간단히도 구현가능합니다..

    ps. 주접을 >_<... 즐프 & 즐타