线程怪问题(122分)

  • 主题发起人 主题发起人 zyx0404
  • 开始时间 开始时间
Z

zyx0404

Unregistered / Unconfirmed
GUEST, unregistred user!
环境:
Delphi 6, Windows XP
程序过程:
步骤1: 在主程序中创建一个线程,该线程弹出一个对话框
步骤2: 主程序从0开始循环计数,当到10时,将线程的对话框关闭
步骤3: 跳到步骤1运行
问题:
主程序计数到10的时候,程序停止运行。
奇怪的是:
1。如果移动一下鼠标,那么对话框就能被关闭,程序继续运行。
2。如果按键盘上的任何一个键,那么对话框就能被关闭,程序继续运行。
3。如果把鼠标放在对话框上,那么当主程序计数到10的时候,能关闭对话框,程序可以继续运行。
注:本人只有122分了,现在全部拿出了
 
线程代码拿来看看
 
主程序从0开始循环计数也是一个线程
StartCountThread;
//计数线程
ThreadDlgCount;
//对话框线程
//对话框线程函数
procedure TfrmMain.ThreadDlgCount;
begin
dlgCountThread := TdlgCountThread.Create(self);
dlgCountThread.ShowModal;
end;

//计数线程函数
procedure TfrmMain.StartCountThread;
begin
m_threadCount := TFormThread.Create(self, False)
end;

//计数线程定义
TFormThread = class(TThread)
private
m_frm : TfrmMain
public
Constructor Create(AOwner : TfrmMain;
CreateSuspended : Boolean);
protected
procedure Execute;
override;
end;
//-----------------------------------------------------------------------------
// Create
//-----------------------------------------------------------------------------
Constructor TFormThread.Create(AOwner : TfrmMain;
CreateSuspended : Boolean);
begin
m_frm := AOwner;
inherited Create(CreateSuspended);
end;

//-----------------------------------------------------------------------------
// Execute
//-----------------------------------------------------------------------------
procedure TFormThread.Execute;
begin
m_frm.ThreadCount;
end;
//-----------------------------------------------------------------------------
// ThreadCount
//-----------------------------------------------------------------------------
procedure TfrmMain.ThreadCount;
var
i : Integer;
begin
i := 0;
while (i < 10)
i := i + 1;
dlgCountThread.Close;
//关闭对话框
end;
 
凡是在主线程外使用form的,都应该用Synchronize()来包起来调用。你那个showmodal用的不对,windows机制将会把主线程给pause,你在窗口线程中用上述函数包起来,调用execute执行看看。
 
使用Synchronize()由主线程来调用可视控件,实现线程同步
 
章译文,请问具体怎么用啊?我试了试,我还不太会用,用了后程序死机,对话框都没有显示出来。应该怎么样写才对?
 
只说Synchronize的用法:
建议学会看Online help
procedure TFormThread.SyncProc
begin
m_frm.ThreadCount;
end;

procedure TFormThread.Execute;
begin
Synchornize(SyncProc);
end;
 
问题不是出在线程上,可能出在TdlgCountThread的窗口代码中。拿出这个窗口代码看一看。
 
to:lab01,
我是看了Online Help,我写的也和你一样。
但程序运行到Synchornize(SyncProc);就不运行m_frm.ThreadCount;
TdlgCountThread没有什么代码
 
你这个不适合用线程,用个定时器就行了。
要调用VCL的东东,就要同步线程。同步线程就会影响主线程的消息循环。
还不如用定时器(Timer),简单省事,稳定。
 
你已经不是调用vcl了,不是同步的问题了
你是在线程内用vcl创建窗体,不合适(线程不安全)
你的问题比较怪,俺昨天试了一下
嘿,俺也是昨天刚请教高手([:)])
// 尽量不要在线程内用类似以下代码
dlgCountThread := TdlgCountThread.Create(self);
dlgCountThread.ShowModal;
 
to : happycyp
我的代码实际上比较复杂,循环计数那断代码非常复杂,我只是简单列举主要的内容
 
to : uiit
请问,你有什么好的解决方法吗?
 
把你的问题一次性搞定——
http://www.delphibox.com/article.asp?articleid=1892
《Delphi6开发人员指南》中文版 ,第131页
 
线程内创建窗体,我没有研究,听说要CreateWindowEx了
我不知道你具体要做什么
但一般情况是主线程创建窗体,然后工作线程处理数据
然后就是资源的同步之类了...
 
试验成功
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TestTh= class(TThread)
private
i:integer;
procedure closeForm;
procedure showI();
public
procedure execute;override;
end;
var
Form1: TForm1;
implementation
uses Unit2;

{$R *.dfm}
procedure TestTH.execute;
var j:integer;
begin
FreeOnTerminate := true;
for j:=0 to 100do
begin
i:=j;
Synchronize(showI);
sleep(1);
end;

Synchronize(closeForm);
end;

procedure TestTH.closeForm;
begin
if form2.Showing then
form2.Close;
end;

procedure TestTh.showI();
begin
form1.Edit1.Text := inttostr(i);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

procedure TForm1.Button1Click(Sender: TObject);
var
t:TestTh;
begin
t:=testth.Create(false);
form2.ShowModal;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
form2.ShowModal;
end;

end.
 
成功了,结贴吧,记得给分呀
 
to : qi_jianzhou
有一个问题,计数循环不是在TestTH.execute里做的,我设计的是在另外一个线程里做
该线程也是由主程序创建的,我正在尝试修改你的代码
 
是一个线程显示对话框,另一个线程关闭这个对话框吗?
 
终于改好了,谢谢各位
按照qi_jianzhou的办法修改一下就可以了
 
后退
顶部