<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Параллельное программирование в Delphi XE7</title>
		<description>Обсуждение Параллельное программирование в Delphi XE7</description>
		<link>http://proghouse.ru/programming/36-delphi-xe7-ppl</link>
		<lastBuildDate>Fri, 17 Apr 2026 04:58:18 +0300</lastBuildDate>
		<generator>JComments</generator>
		<atom:link href="http://proghouse.ru/component/jcomments/feed/com_content/36" rel="self" type="application/rss+xml" />
		<item>
			<title>Ta2i4 написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-2168</link>
			<description><![CDATA[Жаль, что примеров по параллельному программированию на Delphi в гугле пока мало. Сейчас у меня такой код: Всё работает. Но мне понадобилось в этот цикл засунуть еще одну задачу, также стартующую с разными параметрами, которая будет также стартовать с разными параметрами одновременно с первой, но должна быть независима от нее (может завершаться раньше или позже и при необходимости стартовать снова, если первая задача еще не завершена). И вот здесь я наткнулся на проблему.]]></description>
			<dc:creator>Ta2i4</dc:creator>
			<pubDate>Tue, 17 Sep 2019 01:44:50 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-2168</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-1174</link>
			<description><![CDATA[ Правильный способ - это подать сигнал внутреннему потоку, что ему пора завершаться. После этого можно подождать завершения задания. Сигнал можно подать через переменную (например, установив её в true) или событие (TEvent). Плохой способ - это убивать поток задания функцией TerminateThread: https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686717(v=vs.85).aspx.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Mon, 20 Nov 2017 22:45:55 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-1174</guid>
		</item>
		<item>
			<title>ruslan123456 написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-1171</link>
			<description><![CDATA[Как остановить task, если он в данный момент выполняет длительную операцию?]]></description>
			<dc:creator>ruslan123456</dc:creator>
			<pubDate>Sun, 19 Nov 2017 14:16:20 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-1171</guid>
		</item>
		<item>
			<title>Максим написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-802</link>
			<description><![CDATA[ Не знал про volatile. Спасибо за помощь, проблема решена.]]></description>
			<dc:creator>Максим</dc:creator>
			<pubDate>Sun, 19 Mar 2017 20:56:49 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-802</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-801</link>
			<description><![CDATA[ Если у вас Delphi Berlin, то используйте атрибут volatile: http://docwiki.embarcadero.com/RADStudio/Berlin/en/Compiler_Attributes#Volatile, иначе используйте System.TMonitor.Enter: http://docwiki.embarcadero.com/Libraries/Berlin/en/System.TMonitor.Enter(...) - System.TMonitor.Exit: http://docwiki.embarcadero.com/Libraries/Berlin/en/System.TMonitor.Exit(...).]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Sun, 19 Mar 2017 19:25:02 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-801</guid>
		</item>
		<item>
			<title>Максим написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-800</link>
			<description><![CDATA[ В таком случае получается не синхронизированный доступ к переменной, что может привести к плохим последствиям. А если из таска получать эту переменную через Synchronize, то от проблемы мы никуда не уходим. Пока единственное решение, которое мне приходит в голову это вот такой костыль: Вызвать его и ждать пока не отработает таск. Ещё можно HandleMessage заменить на ProcessMessages и Sleep, но смысл тот же.]]></description>
			<dc:creator>Максим</dc:creator>
			<pubDate>Sun, 19 Mar 2017 12:19:49 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-800</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-799</link>
			<description><![CDATA[ Здравствуйте. Вместо вызова Cancel, можете просто завести boolean-переменную, выствлять её в true, если нужно завершить таск, и ждать вызовом Wait. А в таске всё время проверять значение этой переменной, и, если оно true, то завершать таск.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Sun, 19 Mar 2017 07:18:37 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-799</guid>
		</item>
		<item>
			<title>Максим написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-797</link>
			<description><![CDATA[Здравствуйте. Помогите пожалуйста с такой проблемой. Допустим есть объект в котором запускается Task, этот таск после своей работы должен вернуть данные в основной поток, я их возвращаю через TThread.Synchronize. Однако объект может быть разрушен до отработки потока, разрушать объект в котором ещё работает таск не хорошо, нужно как-то заблокировать разрушение объекта, пока не отработает таск. Но сделать это через Wait невозможно, иначе я получу Deadlock, главный поток будет ждать окончания работы таска, а таск будет ждать освобождения главного потока, чтобы выполнить Synchronize. Классно было бы если бы можно вызвать Cancel для таска и внутри не вызывать Synchronize, если было вызвано прерывание. Но если вызвать Cancel, то уже невозможно использовать Wait. Какой-то замкнутый круг, непонятно как решить эту проблему.]]></description>
			<dc:creator>Максим</dc:creator>
			<pubDate>Fri, 17 Mar 2017 13:05:23 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-797</guid>
		</item>
		<item>
			<title>Евгений написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-446</link>
			<description><![CDATA[Спасибо, видимо пропустил:)]]></description>
			<dc:creator>Евгений</dc:creator>
			<pubDate>Tue, 05 Apr 2016 10:38:13 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-446</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-441</link>
			<description><![CDATA[ Посмотрите комментарий #11: http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-142 к этой статье, я там как раз привёл такой пример.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Tue, 05 Apr 2016 08:45:30 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-441</guid>
		</item>
		<item>
			<title>Евгений написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-437</link>
			<description><![CDATA[ А не могли бы сделать небольшой пример? Просто не могу понять как передать адрес функции. Все, что видел в интернете сводится к тому, что тело функции описывается при создании задания. Заранее спасибо за ответ.]]></description>
			<dc:creator>Евгений</dc:creator>
			<pubDate>Mon, 04 Apr 2016 11:43:13 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-437</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-428</link>
			<description><![CDATA[ Можете написать функцию, которая будет принимать на вход, например, адрес сайта и циклично делать то, что вы описали. Затем создать 4 задания, в конструкторе каждому из них передать адрес сайта и адрес этой функции. Затем запустить все эти 4 задания. Только, чтобы сделать паузы, нужно использовать не таймер, а Sleep или TEvent.WaitFor.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Sat, 02 Apr 2016 14:18:10 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-428</guid>
		</item>
		<item>
			<title>Евгений написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-427</link>
			<description><![CDATA[Здравствуйте. Подскажите пожалуйста, как с помощью этого можно реализовать следующее: Есть 4 сайта, с которых с определенной периодичностью нужно получать информацию через их API. Раз, например, в секунду нужно вызывать idhttp.get, получить из него результат и как-то обработать. Я так понимаю, что это будет вызов по таймеру, но нужно, чтобы этот запрос не "вешал" программу, т.к. параллельно должны быть запущены еще 3 таких запроса. При всем при этом пользователь должен продолжать работать с программой. Буду очень признателен за помощь.]]></description>
			<dc:creator>Евгений</dc:creator>
			<pubDate>Sat, 02 Apr 2016 03:36:27 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-427</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-259</link>
			<description><![CDATA[ В этом случае, конечно, код программы не будет простым. Нужно отслеживать, какие элементы массива обработаны, какие не обработаны, какие изменились и их нужно обработать повторно. Также нужно контролировать количество элементов в массиве.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Mon, 02 Nov 2015 09:17:27 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-259</guid>
		</item>
		<item>
			<title>Maximus написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-258</link>
			<description><![CDATA[ А если поток цикла начнёт читать элемент и в этот момент его прервёт основной поток, который не только читает, но и пишет в массив, да ещё и изменяет его размеры? Потом цикл снова возобновит работу и начнётся "веселье".]]></description>
			<dc:creator>Maximus</dc:creator>
			<pubDate>Mon, 02 Nov 2015 01:56:35 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-258</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-251</link>
			<description><![CDATA[Ну, если массив не изменяется, а только читается, можете не использовать TMonitor.Enter и TMonitor.Exit.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Tue, 27 Oct 2015 15:50:10 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-251</guid>
		</item>
		<item>
			<title>Maximus написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-250</link>
			<description><![CDATA[Что делать если мне в TParallel.For необходимо использовать проверку значений массиве структур, описанных вне этого цикла? Вызывать напрямую нельзя, а если ставить TMonitor.Enter и TMonitor.Exit тогда теряется основной смысл параллельной обработки.]]></description>
			<dc:creator>Maximus</dc:creator>
			<pubDate>Tue, 27 Oct 2015 14:28:30 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-250</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-200</link>
			<description><![CDATA[ Официально такое не предусмотрено. Количеством потоков управляет объект TThreadPool и вы можете только изменить минимальное и максимальное количество потоков с помощью свойств MinWorkerThreads и MaxWorkerThreads. Но если очень нужно, то можно прочитать значение из приватных переменных (см. ниже). Но делать это не рекомендуется, т.к. в следующей версии библиотеки PPL всё может поменяться! Если посмотрите исходники, то увидите, что потоками управляет класс TThreadPool, у которого количество потоков хранится в переменной FWorkerThreadCount, а сами потоки - в списке FThreads. Обе эти переменные объявлены в приватной секции, так что напрямую доступа к ним нет. Поэтому используем RTTI, чтобы добраться до приватных переменных. Безопасно читать значение из переменной FWorkerThreadCount не получится, поэтому будем читать количество элементов из списка FThreads. Вот функция, которая вернёт текущее количество потоков: function GetThreadCount(threadPool: TThreadPool): integer; var    rttiContext: TRttiContext;    threadList: TThreadList&lt;TThread&gt;; begin    rttiContext := TRttiContext.Create;    threadList := TThreadList&lt;TThread&gt;(rttiContext.GetType(TTh readPool).GetField('FThreads').GetValue(threadPool ).AsObject);    Result := threadList.LockList.Count;    threadList.UnlockList; end; А вот как ею пользоваться: ShowMessage(IntToStr(GetThreadCount(TThreadPool.De fault))); Чтобы всё заработало, нужно подключить System.Rtti и Generics.Collections. Также нужно учитывать, что в общем пуле потоков будут потоки из разных TParallel.For отрабатывающих в один момент времени. Поэтому, если хотите знать, сколько потоков породилось в определёной TParallel.For, то создайте объект TThreadPool и передайте указатель на него в метод TParallel.For.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Tue, 08 Sep 2015 20:37:00 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-200</guid>
		</item>
		<item>
			<title>Алексей Анатольевич написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-199</link>
			<description><![CDATA[А как узнать текущее количество запущенных с помощью TParallel.For потоков?]]></description>
			<dc:creator>Алексей Анатольевич</dc:creator>
			<pubDate>Tue, 08 Sep 2015 05:37:16 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-199</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-198</link>
			<description><![CDATA[ Естествено вываливается на строке "TTask.WaitForAll(tasks);". У вас же массив из 101 элемента, вы создали только 9 заданий и сохранили указатели на них в начало массива, а остальные 92 элемента массива остались nil. Вот вы и получаете ошибку, что как минимум одно задание в массиве nil. В вашем примере массив должен быть объявлен так: inputdata: array [0..8] of integer;]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Mon, 07 Sep 2015 22:00:57 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-198</guid>
		</item>
		<item>
			<title>Алексей Анатольевич написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-197</link>
			<description><![CDATA[procedure TForm4.Button4Click(Sender: TObject); var i: integer; begin    try       for i := 0 to 8 do       begin          tasks := TTask.Create(TObject(i), TaskProc);          tasks.Start;       end;       memo1.Lines.Add('wait... ');       TTask.WaitForAll(tasks);       memo1.Lines.Add('waited!');       Memo1.Clear;       for i := 0 to 8 do Memo1.Lines.Add('Результат выполнения задачи ' + IntToStr(i) + ': ' + inttostr(inputdata));    finally       for i := 0 to 8 do inputdata:=0;    end; end; Вываливается с ошибкой: First chance exception at $000007FEFD71B3DD. Exception class EArgumentNilException with message 'At least one task in array nil'. Process BG.exe (5676) Последняя запись в мемо при этом: wait... Delphi XE8, Win7x64]]></description>
			<dc:creator>Алексей Анатольевич</dc:creator>
			<pubDate>Mon, 07 Sep 2015 04:05:44 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-197</guid>
		</item>
		<item>
			<title>Алексей Анатольевич написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-196</link>
			<description><![CDATA[{ ... } type    TForm4 = class(TForm) { ... } private    { Private declarations }    tasks: array[0..100] of ITask;    inputdata: array [0..100] of integer;    procedure TaskProc(Sender: TObject); { ... } procedure TForm4.TaskProc(Sender: TObject); var    myIndex: integer; begin    myIndex := Integer(Sender);    Sleep(myIndex * 1000);    System.TMonitor.Enter(self);    try       inputdata[myIndex] := myIndex*myIndex;    finally       System.TMonitor.Exit(self);    end; end;]]></description>
			<dc:creator>Алексей Анатольевич</dc:creator>
			<pubDate>Mon, 07 Sep 2015 04:03:41 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-196</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-142</link>
			<description><![CDATA[Чтобы передать параметры в задание, нужно использовать конструктор Create(Sender: TObject; Event: TNotifyEvent). И здесь уже с помощью первого аргумента (Sender) можно передать что угодно. Вот пример использования: unit Unit1; interface uses    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Threading; type    TForm1 = class(TForm)       Button1: TButton;       Memo1: TMemo;       procedure Button1Click(Sender: TObject);    private       { Private declarations }       tasks: array[0..8] of ITask;       inputdata: array [0..8] of TStrings;       procedure TaskProc(Sender: TObject);    public       { Public declarations }    end; var    Form1: TForm1; implementation {$R *.dfm} procedure TForm1.TaskProc(Sender: TObject); var    myIndex: integer; begin    //Получаем индекс задания.    myIndex := Integer(Sender);    //Что-то делаем.    Sleep(myIndex * 1000);    //Блокируем доступ к общим ресурсам.    System.TMonitor.Enter(self);    try       //Создаём объект TStringList.       inputdata[myIndex] := TStringList.Create;       //Заполняем его.       inputdata[myIndex].Text := 'Задача ' + IntToStr(myIndex) + ' выполнена';    finally       //Разблокируем доступ к общим ресурсам.       System.TMonitor.Exit(self);    end; end; procedure TForm1.Button1Click(Sender: TObject); var    i: integer;    task1: ITask; begin    try       for i := 0 to 8 do       begin          //Инициализируем массив.          inputdata := nil;          //При создании задачи используем конструктор          //class function Create(Sender: TObject; Event: TNotifyEvent): ITask; overload; static; inline;          //и вместо указателя на TObject передаём наш индекс (Integer).          //Вообще здесь можно и нужно передавать указатель на экземпляр класса,          //в котором хранятся необходимые для задачи данные.          tasks := TTask.Create(TObject(i), TaskProc);       end;       //Запускаем задачи.       for task1 in tasks do          task1.Start;       //Ждём завершение всех задач.       TTask.WaitForAll(tasks);       //Выводим результат.       Memo1.Clear;       for i := 0 to 8 do          if assigned(inputdata) then             Memo1.Lines.Add('Результат выполнения задачи ' + IntToStr(i) + ': ' + inputdata.Text);    finally       //Удаляем мусор.       for i := 0 to 8 do          if assigned(inputdata) then             inputdata.Free;    end; end; end.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Fri, 29 May 2015 12:12:55 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-142</guid>
		</item>
		<item>
			<title>Smog написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-141</link>
			<description><![CDATA[Писал код в блокнотие, ИДЕ прям щас под рукой нет, само собой tasks := TTask.Create(procedure()]]></description>
			<dc:creator>Smog</dc:creator>
			<pubDate>Fri, 29 May 2015 11:23:27 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-141</guid>
		</item>
		<item>
			<title>Smog написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-140</link>
			<description><![CDATA[var tasks: array[0....8] of ITask; task1: ITask; inputdata : array [0..8] of TStringsList; Я пытаюсь динамически создавать задания, а не в ручную создавать каждое. for i:=0 to 8 do Begin    tasks := TTask.Create(procedure()	// я так понимаю это фактически анонимный метод       var          task: ITask;          stopwatch, curPos, maxPos: integer;       begin             //вопрос в том как мне передать индекс i внутрь этой констркции             //ЧТобы каждый отдельный ITask работал с inputdata;             //при обычно создании все воркеры будет запущены с i=9 в моем примере             //а я пытаюсь добится tasks[0]->inputdata[0],             //tasks[1]->inputdata[1] и и.д.             //Можно руками запрограмировать если без динамического создания, но если потоков много....          end;); for task1 in tasks do task1.Start;]]></description>
			<dc:creator>Smog</dc:creator>
			<pubDate>Fri, 29 May 2015 10:15:18 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-140</guid>
		</item>
		<item>
			<title>Smog написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-139</link>
			<description><![CDATA[Спасибо огромное за отличную статью, я основной косяк своего прилождения на FMX и PLL уже набросал, благодаря Вашей статье все работает. Нашел 1 странный момент в котором так и не смогу разобратся. ДОпустим есть]]></description>
			<dc:creator>Smog</dc:creator>
			<pubDate>Fri, 29 May 2015 10:14:47 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-139</guid>
		</item>
		<item>
			<title>Smog написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-137</link>
			<description><![CDATA[Спасибо, теперь все очень понятно написано. itasks.Status; не работало потому что взаимодействие с формой через Label6.Text:='0'; нужно делать из Thread.Synchronize.]]></description>
			<dc:creator>Smog</dc:creator>
			<pubDate>Fri, 29 May 2015 09:54:19 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-137</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-135</link>
			<description><![CDATA[Добавил пример для прерывания цикла TParallel.For.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Thu, 28 May 2015 16:00:46 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-135</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-131</link>
			<description><![CDATA[Метод CheckCanceled просто вызывает ошибку EOperationCanceled, если статус Canceled. А что конкретно не заработало со статусом? Происходит ошибка или статус не определяется? У меня ваш код выдаёт 2-ку, а после отмены - 5-ку. Пример с отменой и проверкой статуса добавил в статью.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Wed, 27 May 2015 10:27:30 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-131</guid>
		</item>
		<item>
			<title>Smog написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-130</link>
			<description><![CDATA[Для отмены работы потока помолго: ttask.CurrentTask.CheckCanceled; До єтого конечно надо команду на остановку дать: tasks[2].Cancel; А вот проверка статуса потока, так и не заработала. Код такого вида, упорно не отрабатывает: status:=itasks[2].Status; // status.Running case status of    ttaskstatus(0): Label6.Text:='0';    ttaskstatus(1): Label6.Text:='1';    ttaskstatus(2): Label6.Text:='2';    ttaskstatus(3): Label6.Text:='3';    ttaskstatus(4): Label6.Text:='4';    ttaskstatus(5): Label6.Text:='5';    ttaskstatus(6): Label6.Text:='6'; end;]]></description>
			<dc:creator>Smog</dc:creator>
			<pubDate>Tue, 26 May 2015 19:11:30 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-130</guid>
		</item>
		<item>
			<title>Smog написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-128</link>
			<description><![CDATA[Спасибо огромное! А можно мини пример очистки мусора и выхода из задачи. Как проверять - понял.]]></description>
			<dc:creator>Smog</dc:creator>
			<pubDate>Tue, 26 May 2015 09:58:01 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-128</guid>
		</item>
		<item>
			<title>Alex написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-127</link>
			<description><![CDATA[ Извне вы никак не можете завершить задачу (т.е. поток). Вы только можете оповестить задачу о том, что ей нужно завершиться: вызвать метод Cancel. А внутри процедуры задачи в цикле нужно всё время проверять статус (свойство Status), и, если статус установился в Canceled, то нужно подчищать мусор и выходить из процедуры задачи.]]></description>
			<dc:creator>Alex</dc:creator>
			<pubDate>Tue, 26 May 2015 07:54:32 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-127</guid>
		</item>
		<item>
			<title>Smog написал:</title>
			<link>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-126</link>
			<description><![CDATA[День добрый, как принудительно завершить выполнение потока. Например такого бесконечного цикла внутри потока: itasks[0] := TTask.Create (procedure ()    var       d:Integer;    begin       d:=0;       while d=0 do       begin          sleep (2000); // 2 seconds          TInterlocked.Add (a, 2000);          Label1.Text:=a.ToString;          Progressbar1.Value:=Progressbar1.Value+1;       end;    end );]]></description>
			<dc:creator>Smog</dc:creator>
			<pubDate>Mon, 25 May 2015 21:53:57 +0300</pubDate>
			<guid>http://proghouse.ru/programming/36-delphi-xe7-ppl#comment-126</guid>
		</item>
	</channel>
</rss>
