关于线程,大家帮帮我! to tianlei123:怎么用?能详细点儿吗?谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 给分不多,要求不低!!!waitforsingleobject(要执行的线程的句柄,等待时间或infinite(一直等到线程执行完毕));将该句放在 ***.resume之后 to tianlei123:不要这样,帮帮忙嘛,我的分不多,要不然我肯定多给你加几十分,下次有分了再给你补上,行了吧?谢谢你罗!可是问题还没解决:我的线程***.resume执行后,并没后terminate,而只是挂起了suspend;那我该怎么办? 线程执行到end时已经终止。只是没有free在***.resume之前再加一句:***.FreeOnTerminate:=true; 用了freeonterminate 后用resume好像不能唤醒吧。因为我一定要用resume随时唤醒它。 你到底要干什么?主进程:....***.resume;//唤醒线程执行waitforsingleobject(...,infinite);//等...直到***执行完毕,如果你的线程是死循环,这句永远过不了。....// <-- 这一句除非***执行完才会执行 在主进程中等待会导致程序在等待期间不响应用户输入。可以在线程中直接修改主线程中的变量。如果存在多个线程同时访问同一变量的问题,可以用TCritialSection进行同步。 to lyre:Tcriticalsection 如何用,我在联机帮助里没查到,查书也没找到。另外还问你一个问题: 如何在delphi里面手工触发事件,比如:我要在onclick事件结束立即执行ondoubleclick时间,那在onclick的结尾应该用:ondoubleclick( ),我不知道括号里面的参数如何设?你能举一个事件中参数较多的触发例子给我看一下吗?谢谢! to lyre:能不能给一个Tcriticalsection的例子?谢谢! to lyre: 你怎么不理我呀? 你想取回经线程处理过的变量回来应该有很多办法的我来献上一条最笨的方法:先定义共有变量: type Tvardata=recorderdata : 自定义;new : boolean;end;当有数据要线程处理是置new为false;在线程中处理后在置new为true;不只能不能给点分!方法是土了些但在作线程时这可是一种很有效的方法. to jasminemao(jasmine): 抱歉前段时间没有上网,让你久候了。先给你一个用TCriticalSection的例子://------------------------------------------------------------------//Form的定义object Form1: TForm1 Left = 254 Top = 213 Width = 207 Height = 175 ActiveControl = Button1 Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object SpinEdit1: TSpinEdit Left = 24 Top = 24 Width = 121 Height = 22 MaxValue = 0 MinValue = 0 TabOrder = 0 Value = 9 end object SpinEdit2: TSpinEdit Left = 24 Top = 56 Width = 121 Height = 22 MaxValue = 0 MinValue = 0 TabOrder = 1 Value = 9 end object Button1: TButton Left = 24 Top = 96 Width = 75 Height = 25 Caption = 'Start!' TabOrder = 2 OnClick = Button1Click endend//Form对应的单元unit Unit1;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Sample, StdCtrls, Spin;type TForm1 = class(TForm) SpinEdit1: TSpinEdit; SpinEdit2: TSpinEdit; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);var Thread1, Thread2: TMyThread;begin Thread1 := TMyThread.Create(False); Thread2 := TMyThread.Create(False); SpinEdit1.Value := Thread1.WaitFor; SpinEdit2.Value := Thread2.WaitFor; Beep; Thread1.Free; Thread2.Free;end;end.//Sample单元unit Sample;interfaceuses Classes, SyncObjs, Windows;type TMyThread = class(TThread) procedure Execute; override; end;implementationvar Count: Integer; CS: TCriticalSection;procedure TMyThread.Execute;begin CS.Enter; //进入临界段。可以设想成一个门槛,只允许一个线程进入 try //这里本不必用try..finally..end句式,但这样做是一个好的习惯 while Count > 0 do begin Sleep(1000); //适当延时,增加不同进程冲突的机会 Count := Count -1; end; finally CS.Leave; //离开临界段 end; ReturnValue := Count; //作为WaitFor的返回值end;initialization Count := 1; CS := TCriticalSection.Create;finalization CS.Free;end.//-------------------------------------------------------你可以再把CS.Enter和CS.Leave封掉再看看效果。关于楼上提供的方法: 似乎主线程中要用轮询的方法来查询该值,效率不是很高。而且假如有多个线程同时修改,则不可避免地会导致共享冲突问题。关于你的第二个问题: 一般情况下不需要自己触发事件,可以将组件的该事件重复一下,或调用相应的方法。例如TButton的OnClick可以用TButton.Click触发,一些组件的OnSelect事件则可以将其Selected属性重新赋值。如果坚持要自己触发事件,就要到帮助中查清楚各参数的含义。作为一个惯例,参数中的Sender指的是发生事件的控件。比方说,一个Button1:TButton的OnClick事件要亲自触发,你就得这样写: if Assigned(Button1.OnClick) then Button1.OnClick(Button1);当然,如果按你的要求,在OnClick事件处理程序中再触发OnDoubleClick事件,就可以直接使用Sender: if Assigned(OnDoubleClick) then OnDoubleClick(Sender);说了这么多,不知你满不满意。不满意可以再问,满意的话就给我加点分:-) HTML测试,不好看不要怪我:-)<tr><td><PRE><TT><PRE><TT><PRE><TT><PRE><TT><PRE><TT><FONT COLOR="#000000"><PRE><TT><PRE><TT><font color="#000000"><b>unit</b></font> Sample<font color="#000000">;</font><font color="#000000"><b>interface</b></font><font color="#000000"><b>uses</b></font> Classes<font color="#000000">,</font> SyncObjs<font color="#000000">,</font> Windows<font color="#000000">;</font><font color="#000000"><b>type</b></font> TMyThread <font color="#000000">=</font> <font color="#000000"><b>class</b></font><font color="#000000">(</font>TThread<font color="#000000">)</font> procedure Execute<font color="#000000">;</font> override<font color="#000000">;</font> <font color="#000000"><b>end</b></font><font color="#000000">;</font><font color="#000000"><b>implementation</b></font><font color="#000000"><b>var</b></font> Count<font color="#000000">:</font> <font color="#000000"><b>Integer</b></font><font color="#000000">;</font> CS<font color="#000000">:</font> TCriticalSection<font color="#000000">;</font>procedure TMyThread<font color="#000000">.</font>Execute<font color="#000000">;</font><font color="#000000"><b>begin</b></font> <font color="#7f7f7f"><i>//CS.Enter;</i></font> try <font color="#000000"><b>while</b></font> Count <font color="#000000">></font> <font color="#0000ff">0</font> do <font color="#000000"><b>begin</b></font> Sleep<font color="#000000">(</font><font color="#0000ff">1000</font><font color="#000000">)</font><font color="#000000">;</font> Count <font color="#000000">:</font><font color="#000000">=</font> Count <font color="#000000">-</font><font color="#0000ff">1</font><font color="#000000">;</font> <font color="#000000"><b>end</b></font><font color="#000000">;</font> finally <font color="#7f7f7f"><i>//CS.Leave;</i></font> <font color="#000000"><b>end</b></font><font color="#000000">;</font> ReturnValue <font color="#000000">:</font><font color="#000000">=</font> Count<font color="#000000">;</font><font color="#000000"><b>end</b></font><font color="#000000">;</font>initialization Count <font color="#000000">:</font><font color="#000000">=</font> <font color="#0000ff">1</font><font color="#000000">;</font> CS <font color="#000000">:</font><font color="#000000">=</font> TCriticalSection<font color="#000000">.</font>Create<font color="#000000">;</font>finalization CS<font color="#000000">.</font>Free<font color="#000000">;</font><font color="#000000"><b>end</b></font><font color="#000000">.</font></TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></FONT></TT></PRE></FONT></tr></td> 你可以用TEVENT呀主线程创建了子线程之后就可以WAITFOR了,子线程处理完后SetEvent就可以了。试试看eg:主线程:Wait:TEvent;begin Wait:=TEvnet.Create(nil,false,false,''); //创建子线程 Tss.create(Wait); Wait.WaitFor(5000);子线程: TS1=class (TThread)private evWait:TEvent;...public constructor create(pWait:TEvent);...constructor TS1.create(pWait:TEvent)begin evWait:=pWait; FreeOnTerminate:=true; inherited Create(false);end;...TS1.Execute:.... 处理完之后 evWait.SetEvent;.... 如何通过ScriptControl访问js中的数组元素? DELPHI求解释 周末了,无聊的给我顶 系统热键调用隐藏窗体 Delphi 简单对象问题,急! 又来麻烦各位了,送分,在线 请问如何在一个数据集中确定非空字段? 请问,delphi 7有没有简体中文版? 请问如何可以把 TTreeview.items 和 TListview.items 保存到文件中? 真诚请教指针问题,再次感谢,在线等待 有关TDBImage的问题 我的专家分怎么是负的???????
不要这样,帮帮忙嘛,我的分不多,要不然我肯定多给你加几十分,下次有分了再给你补上,
行了吧?谢谢你罗!
可是问题还没解决:我的线程***.resume执行后,并没后terminate,而只是挂起了suspend;
那我该怎么办?
在***.resume之前再加一句:***.FreeOnTerminate:=true;
....
***.resume;//唤醒线程执行
waitforsingleobject(...,infinite);//等...直到***执行完毕,如果你的线程是死循环,这句永远过不了。
....// <-- 这一句除非***执行完才会执行
如果存在多个线程同时访问同一变量的问题,可以用TCritialSection进行同步。
Tcriticalsection 如何用,我在联机帮助里没查到,查书也没找到。
另外还问你一个问题:
如何在delphi里面手工触发事件,比如:我要在onclick事件结束立即执行ondoubleclick时间,那在onclick的结尾应该用:ondoubleclick( ),我不知道括号里面的参数如何设?你能举一个事件中参数较多的触发例子给我看一下吗?
谢谢!
能不能给一个Tcriticalsection的例子?谢谢!
你怎么不理我呀?
我来献上一条最笨的方法:
先定义共有变量:
type Tvardata=recorder
data : 自定义;
new : boolean;
end;
当有数据要线程处理是置new为false;
在线程中处理后在置new为true;
不只能不能给点分!方法是土了些
但在作线程时这可是一种很有效的方法.
抱歉前段时间没有上网,让你久候了。先给你一个用TCriticalSection的例子://------------------------------------------------------------------
//Form的定义
object Form1: TForm1
Left = 254
Top = 213
Width = 207
Height = 175
ActiveControl = Button1
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object SpinEdit1: TSpinEdit
Left = 24
Top = 24
Width = 121
Height = 22
MaxValue = 0
MinValue = 0
TabOrder = 0
Value = 9
end
object SpinEdit2: TSpinEdit
Left = 24
Top = 56
Width = 121
Height = 22
MaxValue = 0
MinValue = 0
TabOrder = 1
Value = 9
end
object Button1: TButton
Left = 24
Top = 96
Width = 75
Height = 25
Caption = 'Start!'
TabOrder = 2
OnClick = Button1Click
end
end//Form对应的单元
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Sample,
StdCtrls, Spin;type
TForm1 = class(TForm)
SpinEdit1: TSpinEdit;
SpinEdit2: TSpinEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
var
Thread1, Thread2: TMyThread;
begin
Thread1 := TMyThread.Create(False);
Thread2 := TMyThread.Create(False); SpinEdit1.Value := Thread1.WaitFor;
SpinEdit2.Value := Thread2.WaitFor; Beep;
Thread1.Free;
Thread2.Free;
end;end.//Sample单元
unit Sample;interface
uses
Classes, SyncObjs, Windows;type
TMyThread = class(TThread)
procedure Execute; override;
end;implementation
var
Count: Integer;
CS: TCriticalSection;procedure TMyThread.Execute;
begin
CS.Enter; //进入临界段。可以设想成一个门槛,只允许一个线程进入
try //这里本不必用try..finally..end句式,但这样做是一个好的习惯
while Count > 0 do
begin
Sleep(1000); //适当延时,增加不同进程冲突的机会
Count := Count -1;
end;
finally
CS.Leave; //离开临界段
end; ReturnValue := Count; //作为WaitFor的返回值
end;initialization
Count := 1;
CS := TCriticalSection.Create;
finalization
CS.Free;
end.//-------------------------------------------------------
你可以再把CS.Enter和CS.Leave封掉再看看效果。关于楼上提供的方法:
似乎主线程中要用轮询的方法来查询该值,效率不是很高。而且假如有多个线程同时修改,则不可避免地会导致共享冲突问题。关于你的第二个问题:
一般情况下不需要自己触发事件,可以将组件的该事件重复一下,或调用相应的方法。例如
TButton的OnClick可以用TButton.Click触发,一些组件的OnSelect事件则可以将其Selected属性重新赋值。如果坚持要自己触发事件,就要到帮助中查清楚各参数的含义。作为一个惯例,参数中的Sender指的是发生事件的控件。比方说,一个Button1:TButton的OnClick事件要亲自触发,你就得这样写:
if Assigned(Button1.OnClick) then
Button1.OnClick(Button1);
当然,如果按你的要求,在OnClick事件处理程序中再触发OnDoubleClick事件,就可以直接使用Sender:
if Assigned(OnDoubleClick) then
OnDoubleClick(Sender);说了这么多,不知你满不满意。不满意可以再问,满意的话就给我加点分:-)
<FONT COLOR="#000000"><PRE><TT><PRE><TT><font color="#000000"><b>unit</b></font> Sample<font color="#000000">;</font><font color="#000000"><b>interface</b></font>
<font color="#000000"><b>uses</b></font>
Classes<font color="#000000">,</font> SyncObjs<font color="#000000">,</font> Windows<font color="#000000">;</font><font color="#000000"><b>type</b></font>
TMyThread <font color="#000000">=</font> <font color="#000000"><b>class</b></font><font color="#000000">(</font>TThread<font color="#000000">)</font>
procedure Execute<font color="#000000">;</font> override<font color="#000000">;</font>
<font color="#000000"><b>end</b></font><font color="#000000">;</font><font color="#000000"><b>implementation</b></font>
<font color="#000000"><b>var</b></font>
Count<font color="#000000">:</font> <font color="#000000"><b>Integer</b></font><font color="#000000">;</font>
CS<font color="#000000">:</font> TCriticalSection<font color="#000000">;</font>procedure TMyThread<font color="#000000">.</font>Execute<font color="#000000">;</font>
<font color="#000000"><b>begin</b></font>
<font color="#7f7f7f"><i>//CS.Enter;</i></font>
try
<font color="#000000"><b>while</b></font> Count <font color="#000000">></font> <font color="#0000ff">0</font> do
<font color="#000000"><b>begin</b></font>
Sleep<font color="#000000">(</font><font color="#0000ff">1000</font><font color="#000000">)</font><font color="#000000">;</font>
Count <font color="#000000">:</font><font color="#000000">=</font> Count <font color="#000000">-</font><font color="#0000ff">1</font><font color="#000000">;</font>
<font color="#000000"><b>end</b></font><font color="#000000">;</font>
finally
<font color="#7f7f7f"><i>//CS.Leave;</i></font>
<font color="#000000"><b>end</b></font><font color="#000000">;</font>
ReturnValue <font color="#000000">:</font><font color="#000000">=</font> Count<font color="#000000">;</font>
<font color="#000000"><b>end</b></font><font color="#000000">;</font>initialization
Count <font color="#000000">:</font><font color="#000000">=</font> <font color="#0000ff">1</font><font color="#000000">;</font>
CS <font color="#000000">:</font><font color="#000000">=</font> TCriticalSection<font color="#000000">.</font>Create<font color="#000000">;</font>
finalization
CS<font color="#000000">.</font>Free<font color="#000000">;</font>
<font color="#000000"><b>end</b></font><font color="#000000">.</font>
</TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></TT></PRE></FONT></TT></PRE></FONT>
</tr></td>
主线程创建了子线程之后就可以WAITFOR了,子线程处理完后SetEvent就可以了。试试看
eg:
主线程:
Wait:TEvent;
begin
Wait:=TEvnet.Create(nil,false,false,'');
//创建子线程
Tss.create(Wait);
Wait.WaitFor(5000);
子线程:
TS1=class (TThread)
private
evWait:TEvent;
...
public
constructor create(pWait:TEvent);
...
constructor TS1.create(pWait:TEvent)
begin
evWait:=pWait;
FreeOnTerminate:=true;
inherited Create(false);
end;
...
TS1.Execute:
....
处理完之后
evWait.SetEvent;
....