当前位置:主页>delphi盒子/delphi园地/编程技巧> 文章内容

线程设置为运行结束时自动释放实例的FreeOnTerminate=true,如何检测所有生成的线程全部释放,多谢

发布时间:2010-01-22 | QQ免费站
1楼: 线程设置为运行结束时自动释放实例的FreeOnTerminate=true 如何检测所有生成的线程全部释放,多谢 线程的数量是动态生成的 字串3

2楼: 希望以下这段转发代码会对你有所帮助。 -------------------------- // 获取用户组线程 TGetUserGroupsThead = class(TThread) private FOwnerHandle: HWND; FUnitId: WideString; FParentNode, tmpParentNode: TTreeNode; FtvUnits: TTreeView; FRecursive: Boolean; FIsExpandAll: Boolean; FRIO: TMyRIO; // 私有变量 aUserGroup: TUserGroup; p: ^TObject; aNode: TTreeNode; // 线程结束时通知父窗口 procedure FinalAct(Sender: TObject); // 查询 procedure ListChildNode(parentId: String; parentNode: TTreeNode); // 同步添加节点 procedure AddNode; protected // 线程执行体 procedure Execute; override; public // 构造函数 constructor Create(// 所有者窗口句柄 const OwnerHandle: HWND; // 远程操作组件 RIO: TMyRIO; // 单元ID UnitId: WideString; // 是否查询子单元 IsRecursive: Boolean; // 父节点 ParentNode: TTreeNode; // 节点 tvUnits: TTreeView; // 是否全部展开 IsExpandAll: Boolean=true); end; { TGetUserGroupsThead } // 操作VCL组件,该方法必须同步调用 procedure TGetUserGroupsThead.AddNode; begin aNode := FtvUnits.Items.AddChildObject(tmpParentNode, aUserGroup.UnitName, p); if FIsExpandAll then tmpParentNode.Expand(True); end; constructor TGetUserGroupsThead.Create(const OwnerHandle: HWND; RIO: TMyRIO; UnitId: WideString; IsRecursive: Boolean; ParentNode: TTreeNode; tvUnits: TTreeView; IsExpandAll: Boolean); begin FOwnerHandle := OwnerHandle; FRIO := RIO; FUnitId := UnitId; FRecursive := IsRecursive; FParentNode := ParentNode; FtvUnits := tvUnits; FIsExpandAll := IsExpandAll; OnTerminate := FinalAct; FreeOnTerminate := True; inherited Create(False); end; procedure TGetUserGroupsThead.Execute; begin CoInitialize(nil); ListChildNode(FUnitId, FParentNode); end; procedure TGetUserGroupsThead.FinalAct(Sender: TObject); begin // 通知窗口线程已经结束 PostMessage(FOwnerHandle, WM_GetUnitsTheadDoneMsg, 0, 0); end; procedure TGetUserGroupsThead.ListChildNode(parentId: String; parentNode: TTreeNode); var rs: ArrayOf_tns1_UserGroup; i: Integer; begin // 下面是通过WebService取得用户组列表,你不用管 FRIO.Acquire; try rs := FRIO.ua.userGroupSearchUserGroups(FRIO.UserAuthConnection.LoginId, FRIO.UserAuthConnection.LoginPwd, parentId, UA_FALSE); finally FRIO.Release; end; // 递归添加树型节点,因为只能每次取得当前节点的子节点所以使用了递归(服务器端接口的限制) for i := Low(rs) to High(rs) do begin aUserGroup := TUserGroup.Create; aUserGroup.aUserGroup := rs[i]; aUserGroup.UserAuthConnection := FRIO.UserAuthConnection; new(p); p^ := aUserGroup; tmpParentNode := parentNode; // 使用同步方法添加到form上的TreeView控件中 Synchronize(AddNode); aUserGroup.Owner := aNode; if FRecursive then ListChildNode(aUserGroup.UserGroupId, aNode); end; end; 字串8

3楼: 动态创建线程,用TList来记录!最后检查
字串3

4楼: 用WaitForSingleObject等一下就知道了 if (WaitForSingleObject(AThread.Handle,1000) == Wait_Object_0)// 这表示线程终止了 如果多个线程可用WaitForMutiObject,第一个参数为多个线程数组的首址,第二个参数如果为 WAIT_ALL表示等所有的线程 字串6

5楼: china_jian 动态创建线程,用TList来记录!最后检查 大侠,可以给个示例函数吗 多谢了 字串6

6楼: 就是用个数组(或TList)来保存你所创建线程的Thread.Handle,  用WaitForSingleObject依次等,如果用WaitForMutiObject效率高一些
字串8

7楼: WaitForMultipleObjects 怎么用啊 多谢了 字串5

8楼: 函数WaitForMultipleObjects可以同时监测多个同步对象,该函数的声明为: DWORD WaitForMultipleObjects(DWORD nCount, CONST HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds );   参数nCount是句柄数组中句柄的数目。lpHandles代表一个句柄数组。bWaitAll说明了等待类型,如果为TRUE,那么函数在所有对象都有信号后才返回,如果为FALSE,则只要有一个对象变成有信号的,函数就返回。函数的返回值在表12.2中列出。参数dwMilliseconds是以毫秒为单位的超时间隔,如果该参数为0,那么函数就测试同步对象的状态并立即返回,如果该参数为INFINITE,则超时间隔是无限的。   表12.2 WaitForMultipleObjects的返回值 返回值 说明 WAIT_OBJECT_0到WAIT_ OBJECT_0+nCount-1 若bWaitAll为TRUE,则返回值表明所有对象都是有信号的。如果bWaitAll为FALSE,则返回值减去WAIT_OBJECT_0就是数组中有信号对象的最小索引。 WAIT_ABANDONED_0到WAIT_ ABANDONED_ 0+nCount-1 若bWaitAll为TRUE,则返回值表明所有对象都有信号,但有一个mutex被放弃了。若bWaitAll为FALSE,则返回值减去WAIT_ABANDONED_0就是被放弃mutex在对象数组中的索引。 WAIT_TIMEOUT 超时返回。  

字串7

9楼: CONST HANDLE *lpHandles 这个参数怎么用啊 比如 我创建了一个 ThreadList: TList; 使用 ThreadList.Add(TMyThread.Create(ID)); 如何写检测是否完成的线程 if WaitForMultipleObjects(ThreadList.Count, @ThreadList, True, INFINITE) <> WAIT_OBJECT_0 + ThreadList.Count - 1 then begin // 判断此时所有的线程没有结束 end 这样写对吗? 字串9

10楼: 在构造函数中,将自身加入一个链表, 析构时,从此链表中删除, 用TList 就可以 注意,保护临界区变量,互斥访问,包括主线程 使用 TThreadList 也可以 字串4

11楼: var ThreadList: TList; 添加: ThreadList.Add(Pointer(TMyThread.Create(False).Handle)); 判断: if WaitForMultipleObjects(ThreadList.Count, @ThreadList.List, True, INFINITE) then 字串8