begin
inherited;
while(not terminated) do begin
try
Application.ProcessMessages;
synchronize(invoke);
sleep(100);
except on E:Exception do
showMessage(E.Message);
end;
end;
end;
procedure TMyThread.invoke;
var
buf:array[0..1024] of char;
begin
with form1 do begin
TcpClient1.ReceiveBuf(buf,1000,0);
if buf<>'' then begin
StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
StringGrid1.RowCount:=StringGrid1.RowCount+1;
inc(count);
label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
end;
end;
end;
我要从服务器端不断的接收信息来, 但是当没有信息从server端出来时, 整个程序就像死了一样,不再响应任何操作,如果把 synchronize(invoke) 中的"synchronize" 去掉的话就没有这种情况, 可是这样一来,每当关闭该程序时又会出现一个异常,可能是因为线程里操作了vcl控件的原因故而加上synchronize 在关闭时就没有问题了. 我现在的问题是: 当server端没有信息发出来时如何让 线程让出 CPU来以便可以响应程序的其它操作.
望各位大侠不吝赐教, 小弟不胜感激. 如果愿意的话请留QQ,或是MSN,本人的QQ:342853167,Msn:dengy1979@hotmail.com
6 个解决方案
#1
Sleep(0);
#2
Application.ProcessMessages;
這句有問題, 要去掉!
如你這種情況, 你應該在線程中用 PostMessage 向主線程發送一條接收到數據結核的消息,
然後, 讓主線程去處理顯示的問題, 而不是在線程中操作 UI 界面!
synchronize 在這裹作用不明顯, 我估計去掉也不會去錯才對!
這句有問題, 要去掉!
如你這種情況, 你應該在線程中用 PostMessage 向主線程發送一條接收到數據結核的消息,
然後, 讓主線程去處理顯示的問題, 而不是在線程中操作 UI 界面!
synchronize 在這裹作用不明顯, 我估計去掉也不會去錯才對!
#3
信号量
#4
你的这个线程没有太大的意义,没有数据的时候线程也在无效的循环
而且还用synchronize这个函数,这个还是就是把操作控件的代码放到主线程中的
所以你还不如在主线程的接受事件里写代码呢.
Application.ProcessMessages;
synchronize(invoke);
sleep(100);
这三句话都回使线程挂起在恢复,效率很低,尤其是synchronize这个函数附带的操作很多.
你的线程关闭出现异常可这这样看看
MyThread.Terminate;
MyThread.Waitfor;
解决问题比较好的方法是用线程同步和WaitForMultipleObjects函数才能高效运行.
或者平常把线程挂起,在接受事件触发时唤起线程
而且还用synchronize这个函数,这个还是就是把操作控件的代码放到主线程中的
所以你还不如在主线程的接受事件里写代码呢.
Application.ProcessMessages;
synchronize(invoke);
sleep(100);
这三句话都回使线程挂起在恢复,效率很低,尤其是synchronize这个函数附带的操作很多.
你的线程关闭出现异常可这这样看看
MyThread.Terminate;
MyThread.Waitfor;
解决问题比较好的方法是用线程同步和WaitForMultipleObjects函数才能高效运行.
或者平常把线程挂起,在接受事件触发时唤起线程
#5
同上,mark.
#6
你知道线程什么意思吗?
知道synchronize是干什么的吗?
var
buf:array[0..1024] of char; //TMyThread的私有变量
procedure TMyThread.Execute;
begin
while(not terminated) do begin
try
TcpClient1.ReceiveBuf(buf,1000,0);//TcpClient1在线程里创建最好,如果不,传进来也行
if buf<>'' then begin
synchronize(invoke);
TcpClient1.WaitForData();
except on E:Exception do
//showMessage(E.Message);不要这样吗,有异常可以写日志,真弹窗口麻烦就大了
end;
end;
end;
procedure TMyThread.invoke;
begin
with form1 do begin
StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
StringGrid1.RowCount:=StringGrid1.RowCount+1;
inc(count);
label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
end;
end;
知道synchronize是干什么的吗?
var
buf:array[0..1024] of char; //TMyThread的私有变量
procedure TMyThread.Execute;
begin
while(not terminated) do begin
try
TcpClient1.ReceiveBuf(buf,1000,0);//TcpClient1在线程里创建最好,如果不,传进来也行
if buf<>'' then begin
synchronize(invoke);
TcpClient1.WaitForData();
except on E:Exception do
//showMessage(E.Message);不要这样吗,有异常可以写日志,真弹窗口麻烦就大了
end;
end;
end;
procedure TMyThread.invoke;
begin
with form1 do begin
StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
StringGrid1.RowCount:=StringGrid1.RowCount+1;
inc(count);
label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
end;
end;
#1
Sleep(0);
#2
Application.ProcessMessages;
這句有問題, 要去掉!
如你這種情況, 你應該在線程中用 PostMessage 向主線程發送一條接收到數據結核的消息,
然後, 讓主線程去處理顯示的問題, 而不是在線程中操作 UI 界面!
synchronize 在這裹作用不明顯, 我估計去掉也不會去錯才對!
這句有問題, 要去掉!
如你這種情況, 你應該在線程中用 PostMessage 向主線程發送一條接收到數據結核的消息,
然後, 讓主線程去處理顯示的問題, 而不是在線程中操作 UI 界面!
synchronize 在這裹作用不明顯, 我估計去掉也不會去錯才對!
#3
信号量
#4
你的这个线程没有太大的意义,没有数据的时候线程也在无效的循环
而且还用synchronize这个函数,这个还是就是把操作控件的代码放到主线程中的
所以你还不如在主线程的接受事件里写代码呢.
Application.ProcessMessages;
synchronize(invoke);
sleep(100);
这三句话都回使线程挂起在恢复,效率很低,尤其是synchronize这个函数附带的操作很多.
你的线程关闭出现异常可这这样看看
MyThread.Terminate;
MyThread.Waitfor;
解决问题比较好的方法是用线程同步和WaitForMultipleObjects函数才能高效运行.
或者平常把线程挂起,在接受事件触发时唤起线程
而且还用synchronize这个函数,这个还是就是把操作控件的代码放到主线程中的
所以你还不如在主线程的接受事件里写代码呢.
Application.ProcessMessages;
synchronize(invoke);
sleep(100);
这三句话都回使线程挂起在恢复,效率很低,尤其是synchronize这个函数附带的操作很多.
你的线程关闭出现异常可这这样看看
MyThread.Terminate;
MyThread.Waitfor;
解决问题比较好的方法是用线程同步和WaitForMultipleObjects函数才能高效运行.
或者平常把线程挂起,在接受事件触发时唤起线程
#5
同上,mark.
#6
你知道线程什么意思吗?
知道synchronize是干什么的吗?
var
buf:array[0..1024] of char; //TMyThread的私有变量
procedure TMyThread.Execute;
begin
while(not terminated) do begin
try
TcpClient1.ReceiveBuf(buf,1000,0);//TcpClient1在线程里创建最好,如果不,传进来也行
if buf<>'' then begin
synchronize(invoke);
TcpClient1.WaitForData();
except on E:Exception do
//showMessage(E.Message);不要这样吗,有异常可以写日志,真弹窗口麻烦就大了
end;
end;
end;
procedure TMyThread.invoke;
begin
with form1 do begin
StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
StringGrid1.RowCount:=StringGrid1.RowCount+1;
inc(count);
label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
end;
end;
知道synchronize是干什么的吗?
var
buf:array[0..1024] of char; //TMyThread的私有变量
procedure TMyThread.Execute;
begin
while(not terminated) do begin
try
TcpClient1.ReceiveBuf(buf,1000,0);//TcpClient1在线程里创建最好,如果不,传进来也行
if buf<>'' then begin
synchronize(invoke);
TcpClient1.WaitForData();
except on E:Exception do
//showMessage(E.Message);不要这样吗,有异常可以写日志,真弹窗口麻烦就大了
end;
end;
end;
procedure TMyThread.invoke;
begin
with form1 do begin
StringGrid1.Rows[StringGrid1.RowCount-1].Add(IntToStr(count+1));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(DateTimeToStr(Now()));
StringGrid1.Rows[StringGrid1.RowCount-1].Add(buf);
StringGrid1.RowCount:=StringGrid1.RowCount+1;
inc(count);
label6.Caption:='Now receive '+IntToStr(count)+' pieces of message!';
end;
end;