一些帮助TThread(终止,FreeOnTerminate和线程领域的其他冒险)

时间:2010-08-13 12:45:28

标签: multithreading delphi delphi-7 tthread

我正在尝试实现以下(使用Delphi7): 登录到我的程序后,用户获得控制权,但在后台,一个单独的线程从Internet下载文件以检查当前的许可证密钥是否被列入黑名单。如果是,则用户收到提示并且程序终止。

所以我创建了一个单独的TThread类,它使用InternetOpenURL / InternetReadFile从网上下载黑名单。

我的问题如下:

如果用户在后台下载完成之前退出我的程序,则主线程应终止许可证管理器线程。

如果线程完成了它的工作,它应该自动终止。

如果我使用FreeOnTerminate:= true我无法从主线程终止线程。但除此之外,如何在完成工作后让线程释放资源?

我的另一个问题是:

如果许可证密钥被列入黑名单,我使用Synchronize对应用程序主表单的某些资源执行某些操作。

但是,我怎么知道用户是否已经关闭了应用程序,并且程序是在主窗体的FormDestroy中,例如?如果我在错误的时间内同步,可能会导致访问违规......

谢谢!

3 个答案:

答案 0 :(得分:1)

首先,在检查线程对象中,创建一个“已完成”标志。您可以检查这是否属实,以确定是否一切正常。正如Chris T建议的那样,让线程设置一个全局来表示事情好/坏,这样主线程就可以使用类似计时器的东西来检查它并且一切正常或采取适当的行动。

然后,如果您的应用想要提前退出,请致电

  MyThread.Terminate;
  MyThread.WaitFor;

在线程中,检查Terminated是否在适当的位置设置。这样你可以很好地关闭。

答案 1 :(得分:0)

对于第二个问题,不要费心从线程更新UI。只需设置一个全局标志。即IsBlackListed:= true; 现在,您可以使用该全局标志作为唠叨用户的基础,以响应某些用户启动的操作。比如OnFileSave ...... ShowMessage('我很乐意为你保存该文件,但不幸的是,你使用的是黑名单密钥。');

IsBlackListed Redux ....

// globally...
var
  IsBlackListed  : integer;

...
initialization
  IsBlackListed  := 0;

...
// in your thread:
if OhMyGodThisIsABlackListedKey then
  IsBlackListed := 1;

... Back in the main code, maybe in the OnSaveMyData event:

if IsBlackListed then
begin
  IsBlackListed := -1; // so we don't repeat ourselves
  MessageBox('Hey, you naughty pirate!');
  MyDBConnection.Whatever.DoSQL('insert into licensetable (name,key) values(pirate,blacklisted);
end;

答案 2 :(得分:-1)

我认为这就是你要做的事情....将一个OnTerminate()事件分配给TThread,当工作线程终止时,它将作为主线程的一部分被执行。您可以在那里进行所有UI更新(黑名单)。创建工作线程的属性,例如“DownloadComplete”,并且只有在OnTerminated事件中将其设置为true时才进行黑名单/验证。这应该允许线程在程序运行时无论下载状态如何都自由,只要你在程序退出之前使用.watifor()就可以了。