使用了线程后程序莫名其妙的死了,内详,请高手指点指点(100分)

  • 主题发起人 主题发起人 xiaoyue_a
  • 开始时间 开始时间
X

xiaoyue_a

Unregistered / Unconfirmed
GUEST, unregistred user!
我用tcpclient和tcpserver传文件。在传输的过程中想显示进度、速度
开始这么写的
while aStream.Position < aStream.Sizedo
begin
if aStream.Size - aStream.Position >= SizeOf(Buf) then
ReadCount := SizeOf(Buf)
else
ReadCount := aStream.Size - aStream.Position;
aStream.ReadBuffer(Buf, ReadCount);
aIdTCPClient.WriteBuffer(Buf, ReadCount);
{
显示进度的操作
}
application.ProcessMessages;
end;

当我把显示进度的操作做成一个线程时,上传文件时程序会死掉 不知道是什么原因
进程是这么写的
procedure UploadMonitor.Execute;
begin
csize := cFileStream.Position;
while csize < cFileStream.Sizedo
begin
if cFileStream <> nil then
begin
csize := cFileStream.Position;
if cFileStream.Size > 1073741824 then
ProBar.Position := Round(csize / 1024)
else
ProBar.Position := csize;
lbpercent.Caption := IntToStr(Round(csize * 100 / cFileStream.Size)) + '/100%';
lbspeed.Caption := IntToStr(Round((csize - bsize) * 2 / 1024)) + 'K/S';
bsize := csize;
sleep(500);
end
else
break;
end;
end;
 
是不是sleep(500);的问题,sleep会让线程暂停的
换下面这个函数试试:Delay(500);
//延时
procedure Delay(const uDelay: DWORD);
var
n: DWORD;
begin
n := GetTickCount;
while ((GetTickCount - n) <= uDelay)do
Application.ProcessMessages;
end;

//主要是用 Application.ProcessMessages;
让他去处理别的消息,而不是暂停。
 
大家帮帮我啊
 
怎么没人回答我的问题啊
 
在非主线程中操作窗体上的控件的时候,需要使用线程类的 Synchronize 方法
你还是先看看关于TThread类的说明吧
再者:你想在传输的时候让主窗体上显示进度,没有必要单独把控制进度条部分单独拿出来,只要像你上面写的
{
显示进度的操作(不需要在单独的线程中处理)
}
application.ProcessMessages
就可以了
 
我用Synchronize过 可是界面一开始像死了一样
 
那还需要
application.ProcessMessages
 
to:tang_xue_feng
用Synchronize时也要application.ProcessMessages???
 
首先第一个问题,在线程里面访问可视化vcl,必须使用同步;
第二个问题,为什么要sleep(500)?你的这句是什么意思?
先处理这两个问题!
 
可以通过内核对象或者事件来显示的
 
to cqwty
sleep(500)每隔500毫秒监视一次进度
 
线程里面,禁用sleep函数,这是一个致命的错误,虽然很多书上都说,用sleep来实现精度要求不高的时间间隔控制,但是这其实是不可取的。建议这个问题你查一下全文检索,关于定时器的。
还有就是莫明其妙的死了有没有导致相关的出错信息?出现这个情况的时候,你上传的文件是不是都完成了?
 
关注一下,
以前也用过线程 遇到莫明其妙的死机现象
 
to cqwty:没有报错,文件也不传了
 
和我遇到的现象完全一样
就是停在那里不动了
机器也没死掉
非常奇怪
 
用UDP就可以实现了,我还有一个进程显示传输的DEMO。
QQ:136293586
 

if cFileStream.Size > 1073741824 then
ProBar.Position := Round(csize / 1024)
else
ProBar.Position := csize;
lbpercent.Caption := IntToStr(Round(csize * 100 / cFileStream.Size)) + '/100%';
lbspeed.Caption := IntToStr(Round((csize - bsize) * 2 / 1024)) + 'K/S';
写成一个函数,使用Synchronize 调用
 
好象有几个问题:
1、TFileStream是否是多线程安全的。
2、线程中访问界面控件最好同步或发消息,让主线程来刷新界面。
楼主这里可以考虑用TTimer来实现线程部分的功能,会简单很多。
 
呵呵,基本的線程同步問題。
 
郁闷,在线程中改变窗口进度,而上传文件的操作却在主线程中,这样做使用线程有啥用?(最终刷新进度界面还是要在主线程中完成!)
如果要使用线程应该把文件上传操作放在线程中,而进度更新放在主程序中,这样在线程中只须PostMessage 给显示进度的窗口就可以了,界面不会锁死,才能体现使用多线程的效率。
 
后退
顶部