2012-04-27 62 views
0

私のPCは、TCP接続を使用してデータを送信する2つの電子デバイスに接続されています。私はこのすべてのデータをログに記録できるDelphiプログラムを開発したいと思います。次のコードでは、2つのスレッドを使用して2つのTCPClientを作成します。私は1つのスレッドを使用して1つのデバイスからデータをログに記録できますが、2つのスレッドが実行されているときにアプリケーションがフリーズします。私はDelphiでプログラミング経験がありません、あまりにも多くの間違いがあれば申し訳ありません...私はDelphi 7を使用しています。アプリをフリーズするのを避けるために何ができますか? TThreadConn2 .Executeに予め別に(おそらくおそらくいくつかのより多くの助けを借りて、時間に修正されます)全体のデザインからDelphi 7 + Indy +マルチスレッドクライアント

//************************************************************************// 
type TThreadConn1 = class(TThread) 
    private 
    protected 
     procedure Execute; override; 
    end; 

type TThreadConn2 = class(TThread) 
    private 
    protected 
     procedure Execute; override; 
    end; 


var 
    Form1: TForm1; 
    TCP1: TThreadConn1; 
    TCP2: TThreadConn2; 
    flag1: bool; 
    flag2: bool; 


implementation 
{$R *.dfm} 

//******************************Connection 1******************************// 
procedure TThreadConn1.Execute; //Connect+loop read buffer+disconnect 
begin 
    Form1.IdTCPClient1.Connect; 
    While flag1 = false do 
     Form1.IdTCPClient1.CurrentReadBuffer; 
    Form1.IdTCPClient1.Disconnect; 
end; 

procedure TForm1.ButtonConnection1Click(Sender: TObject); 
begin 
    flag1:=false; 
    TCP1 := TThreadConn1.Create(false); //Launch thread 
end; 

procedure TForm1.ButtonDisconnection1Click(Sender: TObject); 
begin 
    flag1:=true; 
    if (TCP1.Terminated = false) then 
     TCP1.Terminate; //Is it ok to finish this way a thread? 
    end; 

//******************************Connection2******************************// 
procedure TThreadConn2.Execute; //Connect+loop read buffer+disconnect 
begin 
    Form1.IdTCPClient2.Connect; 
    While flag2 = false do 
     Form1.IdTCPClient1.CurrentReadBuffer; 
    Form1.IdTCPClient2.Disconnect; 
end; { of procedure } 

procedure TForm1.ButtonConnection2Click(Sender: TObject); 
begin 
    flag2:=false; 
    TCP2 := TThreadConn2.Create(false); 
end; 

procedure TForm1.ButtonDisconnection2Click(Sender: TObject); 
begin 
    flag2:=true; 
    if (TCP2.Terminated = false) then 
     TCP2.Terminate; 
end; 
end. 

答えて

1

同じことをする2つのスレッドを別々に作成する必要はありません。 1つのクラスを作成し、複数のコピーをインスタンス化します。代わりにこれを試してみてください:

type 
    TThreadConn = class(TThread) 
    private 
    FClient: TIdTCPClient; 
    protected 
    procedure Execute; override; 
    public 
    constructor Create(AClient: TIdTCPClient); 
    end; 

var 
    TCP1: TThreadConn = nil; 
    TCP2: TThreadConn = nil; 

constructor TThreadConn.Create(AClient: TIdTCPClient); 
begin 
    inherited Create(False); 
    FClient := AClient; 
end; 

procedure TThreadConn.Execute; 
begin 
    FClient.Connect; 
    try 
    while Terminated = false do 
     FClient.CurrentReadBuffer; 
    finally 
    FClient.Disconnect; 
    end; 
end; 

procedure TForm1.ButtonConnection1Click(Sender: TObject); 
begin 
    TCP1 := TThreadConn.Create(TIdTCPClient1); 
end; 

procedure TForm1.ButtonDisconnection1Click(Sender: TObject); 

は(ゼロ> TCP1 <)場合 を開始し、その後 TCP1.Terminateを開始します。 TCP1.WaitFor; FreeAndNil(TCP1); end; end;

procedure TForm1.ButtonConnection2Click(Sender: TObject); 

TCP2開始:= TThreadConn.Create(IdTCPClient2)を、 end;

procedure TForm1.ButtonDisconnection2Click(Sender: TObject); 
begin 
    if (TCP2 <> nil) then 
    begin 
    TCP2.Terminate; 
    TCP2.WaitFor; 
    FreeAndNil(TCP2); 
    end; 
end; 
+0

ありがとう、あなたのコードは私にとって非常に役に立ちました。それが他の人にも役立つことを願っています。 – user1361263

0

おかげで、あなたは、Form1を呼び出します。 IdTCPClient1 .CurrentReadBuffer。

ヒント:

あなたは、いくつかの異なるクライアントとの通信にスレッドを使用する場合は、フォーム上にplonkないTidTCPClientsを行います。新しいクライアントを追加するたびに、別のインスタンスをフォームに追加して再構築する必要があるため、これは柔軟性がありません。また、あなたのアプリがきれいにシャットダウンされるようにするために、余分な作業が必要になります。

TThread子孫ctorまたは「Execute」メソッドの先頭に動的にTidTCPClientインスタンスを作成します。

試してみて、あなたは、/貼り付けコードをコピーする必要があり、それを編集して、それが誤解しないように、各クライアント接続用にインスタンス化することができる1つのクラスを宣言し

ああ - 今のところ、しないでくださいスレッドをまったく終了させます。実際、永遠にスレッドを試して終了させないでください。 executeでは、成功するまでconnect()をループし、ループ内のものを読み込み、ログに書き込む(スレッドセーフな方法で)。それは永遠にやりなさい。ロギングを停止するには、スレッドを実行してもロガーの呼び出しを気にしないように 'do not log'ブール値を設定します。もう一度 - スレッドを終了しようとするのに近づかないでください。

もし私が週末にチャンスを得るなら、私は簡単な例をとってみましょう。一つのフォーム、二組のホスト名/ポートのための4つのTEdit、そしてサーバーへのデータの送信と表示のための2つのTMemos。

関連する問題