Некоторая помощь с TThread (Terminate, FreeOnTerminate и другие приключения в сфере многопоточности) - PullRequest
2 голосов
/ 13 августа 2010

Я пытаюсь добиться следующего (используя Delphi7): После входа в мою программу пользователь получает контроль, но в фоновом режиме отдельный поток загружает файл из Интернета, чтобы проверить, находится ли текущий лицензионный ключ в черном списке. Если это так, пользователь получает приглашение и программа завершает работу.

Итак, я создал отдельный класс TThread, который загружает черный список из сети, используя InternetOpenURL / InternetReadFile.

Моя проблема заключается в следующем:

Если пользователь выходит из моей программы до завершения загрузки в фоновом режиме, поток менеджера лицензий должен быть прерван основным потоком.

Если поток выполнил свою работу, он должен автоматически завершиться.

Если я использую FreeOnTerminate: = true, я не могу прекратить поток из основного потока. Но в противном случае, как я могу заставить поток освободить свои ресурсы после того, как он выполнил свою работу?

Мой другой вопрос:

Если лицензионный ключ занесен в черный список, я использую Synchronize, чтобы сделать что-то с определенными ресурсами основной формы приложения.

Но как мне узнать, если пользователь уже закрыл приложение и программа находится в FormDestroy основной формы, например? Если я синхронизируюсь не вовремя, это может привести к нарушениям доступа ...

Спасибо!

Ответы [ 3 ]

1 голос
/ 13 августа 2010

Во-первых, в вашем объекте контрольной нити создайте флаг «завершено». Вы можете проверить это верно, чтобы определить, все ли хорошо. Как полагает Крис Т., установите для потока глобальную переменную, указывающую, что все хорошо / плохо, чтобы основной поток мог использовать что-то вроде таймера для проверки того, что все в порядке, или принять соответствующие меры.

Тогда, если ваше приложение хочет выйти раньше, позвоните

  MyThread.Terminate;
  MyThread.WaitFor;

И в потоке проверьте, установлен ли Termination в соответствующих точках. Таким образом, вы можете красиво закрыть.

0 голосов
/ 14 августа 2010

Я думаю, что это то, что вы пытаетесь сделать .... Назначьте событие OnTerminate () для TThread, которое исполняется как часть вашего основного потока, когда рабочий поток завершается. Вы можете делать там все свои обновления пользовательского интерфейса (черный список). Создайте свойство вашего рабочего потока, например «DownloadComplete», и вносите в черный список / проверку только в том случае, если для этого события установлено значение true в событии OnTeridity. Это должно позволить потоку освободиться независимо от состояния загрузки при запуске программы, если вы выполняете ее .watifor () до выхода из программы.

0 голосов
/ 13 августа 2010

По второму вопросу, не беспокойтесь об обновлении пользовательского интерфейса из потока. Просто установите глобальный флаг. то есть 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;
...