M
mouse_ingrief
Unregistered / Unconfirmed
GUEST, unregistred user!
是这样的:
程序的目的是能在两个串口间实现收发;我的操作分四步:1、打开发送串口,
2、打开接受串口,3、开始发送(不停的发),4、开始接受(不停的接受)。
但是我运行程序后,会可能出现这样的情况:1、接受不再继续,2、发送不再接受,
3、发送和接受都不再继续。我也不知道是线程挂起了还是线程执行完毕了,
根据我的代码,线程不可能执行完毕
因为在线程的execute中我是while true do。另外我发现只运行一个线程,或发送或读取
上述情况还没有发生。下面是一些代码:
线程类:
TRead=Class(TThread)
Public procedure Execute;override;
public procedure BeforeRead;
Public procedure AfterRead;
end;
TWrite=Class(TThread)
public procedure Execute;override;
public procedure BeforeWrite;
public procedure AfterWrite;
end;
procedure TRead.BeforeRead;
begin
Form1.StatusBar1.Panels[3].Text :='接受中';
end;
procedure TRead.AfterRead;
begin
Form1.Memo2.Text :=FReadBuf;
form1.StatusBar1.Panels[1].Text :='接收完毕: '+IntToStr(FSizeR)+'个字节';
form1.StatusBar1.Panels[3].Text :='接收完毕';
end;
procedure TRead.Execute;
begin
FReadBuf:=Nil;
FreeOnTerminate:=true;
while true do//如果这个true换成一个变量比如:reading,有时候readfile后reading
//的值就自动改变,原来是true ,现在是false,很奇怪。
begin
//EnterCriticalSection(cs);
Synchronize(BeforeRead);
ClearCommError(FComR,Err,@FStat);
if FStat.cbInQue =0 then Continue else FSizeR:=FStat.cbInQue;
if ReadFile(FComR,FReadBuf,FSizeR,FSizeR,Nil) then
begin
Synchronize(AfterRead);
end;
//LeaveCriticalSection(cs);
end;
PurgeComm(FComR,PURGE_RXCLEAR OR PURGE_RXABORT);
end;
procedure TWrite.BeforeWrite;
begin
Form1.StatusBar1.Panels[2].Text :='发送中';
FWriteBuf:=Pchar(Form1.Memo1.Text);
FSizeS:=StrLen(FWriteBuf);
end;
procedure TWrite.AfterWrite;
begin
Form1.StatusBar1.Panels[0].Text :='发送完毕:'+IntToStr(FSizeS)+'个字节';
Form1.StatusBar1.Panels[2].Text :='发送完毕';
end;
procedure TWrite.Execute;
begin
FWriteBuf:=Nil;
FreeOnTerminate:=true;
while true do
begin
//EnterCriticalSection(cs);
Synchronize(BeforeWrite);
if Terminated then Break;
if WriteFile(FComS,FWritebuf,FSizeS,FSizeS,Nil) then
begin
Synchronize(AfterWrite);
end;
//LeaveCriticalSection(cs);
end;
PurgeComm(FComR,PURGE_TXCLEAR OR PURGE_TXABORT);
end;
1、
var
Form1: TForm1;
FComS,FComR:Thandle;//FComS是发送串口句柄,FComR是接受串口句柄
FDcb:TDCB;
FTm:CommTimeOuts;
FReadBuf,FWriteBufchar;
FSizeS,FSizeRWORD;
FStat:TComstat;
errWORD;
FRead:TRead;
FWrite:TWrite;
writing,reading:boolean;
2、创建线程,并且挂起
procedure TForm1.FormCreate(Sender: TObject);
begin
FRead:=TRead.Create(true);
FWrite:=TWrite.Create(true);
reading:=true;
writing:=true;
end;
3、打开发送串口
procedure TForm1.OpenSendPortClick(Sender: TObject);
begin
FComS:=CreateFile(Pchar('Com'+Combobox1.text),GENERIC_READ or GENERIC_WRITE,0,Nil,OPEN_EXISTING,0,0);
if FComS = INVALID_HANDLE_VALUE then begin Showmessage('Open Com Port Error!');exit;end;
BuildCommDcb(Pchar(edit1.Text),FDcb);
FillChar(FTm,5,0);
FTm.WriteTotalTimeoutMultiplier :=5;
FTM.WriteTotalTimeoutConstant :=100;
SetCommTimeOuts(FComS,FTM);
OpenSendPort.Enabled :=false;
end;
4、打开接受串口
procedure TForm1.OpenRecivePortClick(Sender: TObject);
begin
FComr:=CreateFile(Pchar('Com'+Combobox2.text),GENERIC_READ or GENERIC_WRITE,0,Nil,OPEN_EXISTING,0,0);
if FComr = INVALID_HANDLE_VALUE then begin Showmessage('open com Error');exit;end;
BuildCommDcb(Pchar(edit2.Text),FDcb);
FillChar(FTm,5,0);
FTm.ReadIntervalTimeout :=0;
FTm.ReadTotalTimeoutMultiplier :=5;
FTm.ReadTotalTimeoutConstant :=1000;
SetCommTimeOuts(FComr,FTM);
OpenRecivePort.Enabled :=false;
end;
5、开始发送
procedure TForm1.AutoSendClick(Sender: TObject);
begin
AutoSend.Enabled :=false;
StatusBar1.Panels[2].Text :='自动发送中';
writing:=true;
FWrite.Resume;
end;
6、开始接受
procedure TForm1.BeginReciveClick(Sender: TObject);
begin
reading:=true;
FRead.Resume;
BeginRecive.Enabled :=false;
StatusBar1.Panels[3].Text :='接受中';
end;
贴子太长了,希望各位能心平气和的开完,帮我解答。我自己实在无能为力了。
程序的目的是能在两个串口间实现收发;我的操作分四步:1、打开发送串口,
2、打开接受串口,3、开始发送(不停的发),4、开始接受(不停的接受)。
但是我运行程序后,会可能出现这样的情况:1、接受不再继续,2、发送不再接受,
3、发送和接受都不再继续。我也不知道是线程挂起了还是线程执行完毕了,
根据我的代码,线程不可能执行完毕
因为在线程的execute中我是while true do。另外我发现只运行一个线程,或发送或读取
上述情况还没有发生。下面是一些代码:
线程类:
TRead=Class(TThread)
Public procedure Execute;override;
public procedure BeforeRead;
Public procedure AfterRead;
end;
TWrite=Class(TThread)
public procedure Execute;override;
public procedure BeforeWrite;
public procedure AfterWrite;
end;
procedure TRead.BeforeRead;
begin
Form1.StatusBar1.Panels[3].Text :='接受中';
end;
procedure TRead.AfterRead;
begin
Form1.Memo2.Text :=FReadBuf;
form1.StatusBar1.Panels[1].Text :='接收完毕: '+IntToStr(FSizeR)+'个字节';
form1.StatusBar1.Panels[3].Text :='接收完毕';
end;
procedure TRead.Execute;
begin
FReadBuf:=Nil;
FreeOnTerminate:=true;
while true do//如果这个true换成一个变量比如:reading,有时候readfile后reading
//的值就自动改变,原来是true ,现在是false,很奇怪。
begin
//EnterCriticalSection(cs);
Synchronize(BeforeRead);
ClearCommError(FComR,Err,@FStat);
if FStat.cbInQue =0 then Continue else FSizeR:=FStat.cbInQue;
if ReadFile(FComR,FReadBuf,FSizeR,FSizeR,Nil) then
begin
Synchronize(AfterRead);
end;
//LeaveCriticalSection(cs);
end;
PurgeComm(FComR,PURGE_RXCLEAR OR PURGE_RXABORT);
end;
procedure TWrite.BeforeWrite;
begin
Form1.StatusBar1.Panels[2].Text :='发送中';
FWriteBuf:=Pchar(Form1.Memo1.Text);
FSizeS:=StrLen(FWriteBuf);
end;
procedure TWrite.AfterWrite;
begin
Form1.StatusBar1.Panels[0].Text :='发送完毕:'+IntToStr(FSizeS)+'个字节';
Form1.StatusBar1.Panels[2].Text :='发送完毕';
end;
procedure TWrite.Execute;
begin
FWriteBuf:=Nil;
FreeOnTerminate:=true;
while true do
begin
//EnterCriticalSection(cs);
Synchronize(BeforeWrite);
if Terminated then Break;
if WriteFile(FComS,FWritebuf,FSizeS,FSizeS,Nil) then
begin
Synchronize(AfterWrite);
end;
//LeaveCriticalSection(cs);
end;
PurgeComm(FComR,PURGE_TXCLEAR OR PURGE_TXABORT);
end;
1、
var
Form1: TForm1;
FComS,FComR:Thandle;//FComS是发送串口句柄,FComR是接受串口句柄
FDcb:TDCB;
FTm:CommTimeOuts;
FReadBuf,FWriteBufchar;
FSizeS,FSizeRWORD;
FStat:TComstat;
errWORD;
FRead:TRead;
FWrite:TWrite;
writing,reading:boolean;
2、创建线程,并且挂起
procedure TForm1.FormCreate(Sender: TObject);
begin
FRead:=TRead.Create(true);
FWrite:=TWrite.Create(true);
reading:=true;
writing:=true;
end;
3、打开发送串口
procedure TForm1.OpenSendPortClick(Sender: TObject);
begin
FComS:=CreateFile(Pchar('Com'+Combobox1.text),GENERIC_READ or GENERIC_WRITE,0,Nil,OPEN_EXISTING,0,0);
if FComS = INVALID_HANDLE_VALUE then begin Showmessage('Open Com Port Error!');exit;end;
BuildCommDcb(Pchar(edit1.Text),FDcb);
FillChar(FTm,5,0);
FTm.WriteTotalTimeoutMultiplier :=5;
FTM.WriteTotalTimeoutConstant :=100;
SetCommTimeOuts(FComS,FTM);
OpenSendPort.Enabled :=false;
end;
4、打开接受串口
procedure TForm1.OpenRecivePortClick(Sender: TObject);
begin
FComr:=CreateFile(Pchar('Com'+Combobox2.text),GENERIC_READ or GENERIC_WRITE,0,Nil,OPEN_EXISTING,0,0);
if FComr = INVALID_HANDLE_VALUE then begin Showmessage('open com Error');exit;end;
BuildCommDcb(Pchar(edit2.Text),FDcb);
FillChar(FTm,5,0);
FTm.ReadIntervalTimeout :=0;
FTm.ReadTotalTimeoutMultiplier :=5;
FTm.ReadTotalTimeoutConstant :=1000;
SetCommTimeOuts(FComr,FTM);
OpenRecivePort.Enabled :=false;
end;
5、开始发送
procedure TForm1.AutoSendClick(Sender: TObject);
begin
AutoSend.Enabled :=false;
StatusBar1.Panels[2].Text :='自动发送中';
writing:=true;
FWrite.Resume;
end;
6、开始接受
procedure TForm1.BeginReciveClick(Sender: TObject);
begin
reading:=true;
FRead.Resume;
BeginRecive.Enabled :=false;
StatusBar1.Panels[3].Text :='接受中';
end;
贴子太长了,希望各位能心平气和的开完,帮我解答。我自己实在无能为力了。