Операции в отдельном потоке GUI блока TThread - PullRequest
7 голосов
/ 19 февраля 2011

Я использовал этот учебник http://delphi.about.com/od/kbthread/a/thread-gui.htm, чтобы создать класс, который асинхронно загружает файл из Интернета в другом потоке с TDownLoadURL.Я сделал это, потому что хочу загрузить файл без блокировки потока пользовательского интерфейса, чтобы программа не перестала отвечать на запросы при больших загрузках, индикатор выполнения может обновляться и т. Д.

У меня возникла проблема, потому что, хотя явыполнили загрузку в другом потоке (наследуя от TThread и выполнив работу в методе Execute), поток графического интерфейса, кажется, заблокирован и не обрабатывает сообщения, пока загрузка не будет завершена.Вот код для моего класса: http://codepad.org/nArfOPJK (это всего 99 строк, простой класс).Я выполняю его этим в обработчике событий для нажатия кнопки:

var
    frame: TTProgressFrame;
    dlt: TDownloadThread;
begin
    dlt := TDownloadThread.Create(True);
    dlt.SetFile('C:\ohayo.zip');
    dlt.SetURL('http://download.thinkbroadband.com/512MB.zip');
    dlt.SetFrame(frame);
    dlt.SetApp(Application);
    dlt.Start;

Примечание. Метод SetApp был для того случая, когда я вручную вызывал app.ProcessMessages из метода UpdateDownloadProgress моего классаTDownloadThread.Это не позволит графическому интерфейсу перестать отвечать на запросы, но заставит индикатор выполнения работать странно (движущаяся светящаяся вещь индикатора выполнения аэро движется слишком быстро), поэтому я удалил его.Я хочу исправить это должным образом, и если мне нужно вызвать ProcessMessages, нет смысла многопоточность.

Может кто-нибудь помочь мне решить эту проблему?Спасибо.

1 Ответ

5 голосов
/ 19 февраля 2011

У меня теперь есть решение для вас!

Вызов TDownLoadURL.Execute (ваш вызов dl.Execute в TDownloadThread) приводит к тому, что действие переносится обратно в основной поток, поэтому ваш интерфейс становитсяне отвечает.

Вместо этого следует вызвать ExecuteTarget(nil), который не выполняет таких махинаций и работает так, как вы предполагаете: загрузка выполняется в рабочем потоке.

...