Maximus
-
Постов
84 -
Зарегистрирован
-
Посещение
-
Победитель дней
9
Сообщения, опубликованные Maximus
-
-
А если заюзать асинхронный THTTPClient, то и поток создавать и заботиться о синхронизации не нужно будет.
-
В общем оказалось, что и ITask можно использовать, главное следовать тем же правилам что и при работе с TThread. Если ставим саморазрушение в объект, то извне его разрушать нельзя. А если это всё же необходимо, то придётся убрать саморазрушение после отработки и подождать завершения задачи, в которой можно поставить проверки Task.Status = Canceled для преждевременной остановки задачи.
-
Доброго времени суток. Надеюсь многие пользуются новым средством распараллеливания ITask, подскажите что я делаю с ним не так.
Для теста создал простенький класс
unit ThreadTask; interface uses System.SysUtils, System.Threading, System.Classes; type TOnCollback = procedure(ID: Integer) of object; TThreadTask = class private Task: ITask; procedure Execute; procedure Print; procedure Close; public OnDestroy: TOnCollback; OnPrint: TOnCollback; Destructor Destroy; override; procedure Start; procedure Stop; end; implementation { TThreadTask } procedure TThreadTask.Close; begin if Assigned(OnDestroy) then OnDestroy(Task.Id); end; destructor TThreadTask.Destroy; begin Stop; TThread.Synchronize(TThread.CurrentThread, Close); inherited; end; procedure TThreadTask.Execute; begin TThread.Sleep(3000); TThread.Synchronize(TThread.CurrentThread, Print); TThread.Sleep(3000); TThread.Synchronize(TThread.CurrentThread, Print); Free; end; procedure TThreadTask.Print; begin if Assigned(OnPrint) then OnPrint(Task.Id); end; procedure TThreadTask.Start; begin Task := TTask.Run(Execute); end; procedure TThreadTask.Stop; begin if Assigned(Task) and (Task.Status = TTaskStatus.Running) then Task.Cancel; end; end.
Класс включает в себя интерфейс ITask и после создания и вызова метода Start должен в потоке выполнять какие-то вычисления, в данном случае это просто задержка и вызов коллбека. После отработки класс вызывает коллбек для уведомления о завершении работы и самостоятельно разрушается.
Код использования класса:
unit Unit1; interface uses ..., ThreadTask; type TForm1 = class(TForm) Memo: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); private ThreadTask: TThreadTask; procedure TreadDestroy(ID: Integer); procedure TreadPrint(ID: Integer); public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.Button1Click(Sender: TObject); begin if Assigned(ThreadTask) then FreeAndNil(ThreadTask); ThreadTask := TThreadTask.Create; ThreadTask.OnDestroy := TreadDestroy; ThreadTask.OnPrint := TreadPrint; ThreadTask.Start; end; procedure TForm1.TreadDestroy(ID: Integer); begin Memo.Lines.Add(Format('ThreadTask №%d уничтожен', [ID])); ThreadTask := nil; end; procedure TForm1.TreadPrint(ID: Integer); begin Memo.Lines.Add(Format('Я Task №%d', [ID])); end; end.
По нажатию на кнопку проверяем не существует ли предыдущий экземпляр класса, если существует уничтожаем его, создаём новый и запускаем его. Приходящие сообщения от класса выводим в Memo.
Если запустить и дождаться полной отработки потоком, то всё ожидаемо, в Memo видим:
Я Task №1 Я Task №1 ThreadTask №1 уничтожен
Однако если не дождавшись окончания работы первого потока ещё раз нажать на кнопку, то вывод получается совсем не тем, что ожидалось:
ThreadTask №1 уничтожен Я Task №2 Я Task №2 Я Task №2 ThreadTask №2 уничтожен
Первый класс разрушается, но задача не снимается и кроме того она вызывает лишний раз коллбек от имени второй задачи. Казалось бы можно переписать код кнопки и "занулить" коллбеки:
procedure TForm1.Button1Click(Sender: TObject); begin if Assigned(ThreadTask) then begin ThreadTask.OnDestroy := nil; ThreadTask.OnPrint := nil; FreeAndNil(ThreadTask); end; ThreadTask := TThreadTask.Create; ThreadTask.OnDestroy := TreadDestroy; ThreadTask.OnPrint := TreadPrint; ThreadTask.Start; end;
Но это не даёт нужного результата, вывод в Memo практически аналогичен предыдущему:
Я Task №1 Я Task №1 Я Task №1 ThreadTask №1 уничтожен
Может быть Task нельзя так использовать или я что-то делаю не так?
-
Попробуйте убрать из множества StyledSettings элемент FontColor перед изменением цвета
nad[g].StyledSettings := [TStyledSetting.Family, TStyledSetting.Size, TStyledSetting.Style]; nad[g].FontColor := $FFFEFEFE;
-
Значит всё-таки придётся вручную заменять.
-
На самом деле и THTMLEncoding и TNetEncoding используют один и тот же метод, поэтому результат будет тот же.
-
Добрый день. Возникла проблема при декодировании HTML страницы. При попытке декодировать символ
THTMLEncoding.HTML.Decode(' ');
получаю ошибку
Не хотелось использовать обычную замену, думал использовать специальную функцию для этого, но не вышло... Это очередной баг или перед декодированием текст ещё как-то нужно подготовить?
-
Понял. Значит не исправили ничего.
-
А если BorderStyle=None?
Хмм... так хинты высвечиваются только при использовании обычного VCL
А причём тут VCL?
-
А если BorderStyle=None?
-
Здорово, значит исправили, спасибо.
-
В Seattle Update 1 не исправили, не знаете?
-
Странно, у меня таких проблем не возникает с этим компонентом. Значок пропадает сразу после перетаскивания.
-
-
-
Доброго всем времени суток. Подскажите, есть ли в FireMonkey возможность отслеживать сетевую активность в целом. Чтобы впоследствии можно было бы отобразить сколько байт передано/получено в секуну. Если в Windows это можно реализовать через WinAPI, то что делать с Android и IOS? Универсального средства нет?
-
На семёрке
TOSVersion.Major = 6
TOSVersion.Minor = 1
TOSVersion.Build = 7601
На десятке
TOSVersion.Major = 10
TOSVersion.Minor = 0
TOSVersion.Build= 0
Про Minor погорячился, он и должен быть 0. У вас на скрине как раз Major и Minor. Но почему Build равен нулю, когда по идее должен быть 10586 на последней версии.
-
Доброго времени суток. Замечено, что TOSVersion.Minor и TOSVersion.Build на Windows 10 выдают нули. Баг или для десятки нужен другой способ определения версии?
-
Неполный пример - Integer, как и pointer укладывается в регистр EAX/EBX или какие_там_сейчас_у_процессоров.
С учетом модели вызовов register, используемой в Delphi, для integer выигрыша в передаче по ссылке/по значению нет. Ну, разве что при передаче по ссылке в винде будет PageFault и процессору придется подгружать страничку. Но это крайне маловероятно, с учетом того, что реальное значение было доступно в вызывающем коде.
Поэтому и передается по значению.
Корректнее было бы сравнить string, record и array, ибо
Using const allows the compiler to optimize code for structured - and string-type parameters.Да, вы правы. Со string и class получилось также как и с integer, а вот record и array передались по ссылке и в var, и в const. В любом случае ничего не изменилось в этом плане, в последней версии всё аналогично, а значит править ничего не нужно.
-
да уж ссылочка, почитал, кошмар...теперь ведь все проекты при переходе перелопачивать под "const [Ref]"...жескачь
т.е. везде в новых проектов писать эти 11 знаков? мдя...ладно 5 ну 11 уже слишком да и код не айс становиться
Вообще-то модификатор const никогда не передавал переменную по ссылке, всегда было по значению, ничего не изменилось в этом плане. Наоборот добавили новую возможность передать по ссылке с использованием модификатора const.
наверно вы правы...люди же для красоты или забавы писали const ))
если ваша правда, то значит что указать const что не указать все всегда было одно и тоже...просто делать нечего было...вот и писали const )
Может люди писали его для блокирования возможности изменения переданного параметра? Именно внутри процедуры. Вот вам элементарная проверка, Delphi 7.
procedure TForm1.check_const(const b: integer); begin Label2.Caption := Format('%p', [@b]); end; procedure TForm1.check_var(var c: integer); begin Label3.Caption := Format('%p', [@c]); end; procedure TForm1.check(d: integer); begin Label4.Caption := Format('%p', [@d]); end; procedure TForm1.Button1Click(Sender: TObject); var a: integer; begin a := 1; Label1.Caption := Format('%p', [@a]); check_const(a); check_var(a); check(a); end;
Только при передаче через var адрес остаётся неизменным, а значит передача идёт по ссылке.
-
да уж ссылочка, почитал, кошмар...теперь ведь все проекты при переходе перелопачивать под "const [Ref]"...жескачь
т.е. везде в новых проектов писать эти 11 знаков? мдя...ладно 5 ну 11 уже слишком да и код не айс становиться
Вообще-то модификатор const никогда не передавал переменную по ссылке, всегда было по значению, ничего не изменилось в этом плане. Наоборот добавили новую возможность передать по ссылке с использованием модификатора const.
-
Тогда действительно накосячили они. Видимо стоит ждать фикса, если он будет.
-
HitTest в вашем проекте не false случайно на тех объектах где Hint использовать пытаетесь?
-
Поддержу вопрос, но немного его перефразирую. У меня вообще какой то затык с этим Hint-ом! Как приложение я пишу уже полгода (начал с DelphiEX7), бинт появился только сейчас, то я его добавил только сейчас, но не тут то было! Он вообще не отображается нигде ни при каких обстоятельствах!!!! Что делать? С кем то конфликтует?
В пустом проекте хоть отображается?
Утолщение линии при отрисовке на Canvas
в Отрезок
Опубликовано · Изменено пользователем Maximus
Доброго всем времени суток. Хочу снова поднять вопрос про отрисовку линий на канве, обсуждавшейся здесь
С горизонтальными и вертикальными линиями проблем нет, при смещении на половину от толщины линии всё прекрасно выглядит. Однако при отрисовке линий под различными углами такой финт не проходит: слева VCL, справа FMX
Линия всё так же размазывается, в итоге визуально утолщается и становится не такой чёткой.
Как всё же добиться такого же результата как на VCL? Интересует только Windows.
const OFFSET_LINE = 0.5; ... Image.Bitmap.Canvas.BeginScene; Image.Bitmap.Canvas.Stroke.Kind := TBrushKind.Solid; Image.Bitmap.Canvas.Stroke.Thickness := 1.0; Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(500.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(10.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(500.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.EndScene;