antigrav
-
Постов
25 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные antigrav
-
-
Уважаемый Slym, к сожалению предложенный способ результата не дал. Если я правильно понял, условие
ThreadPoolStats.IdleWorkerThreadCount<>ThreadPoolStats.WorkerThreadCount
является признаком того, что не все таски завершены. При тестировании приложения это условие не выполняется (то есть все такси завершены?), управление передается деструктору главной формы приложения, в котором дается команда на удаление пользовательских объектов. Пользовательские объекты удаляются. Затем выдается сообщение об утечке памяти и приложение закрывается.
-
Спасибо, попробую
-
Здравствуйте, коллеги.
Пишу метод десериализации для считывания данных из файла и создания соответствующего объекта в памяти. Для того, чтобы пользователь не скучал, загружаю данные в отдельном потоке, а в главном запускаю TAniIndicator. Данные считываются, объект создается, AniIndicator работает. Но при попытке завершения приложения получаю утечку памяти (см. рис.). Пользовательские объекты я удаляю перед закрытием приложения, но в памяти остаются системные объекты, в том числе из библиотеки PPL. Сокращенный код метода загрузки данных ниже. С чем может быть связана утечка? Для детектирования утечек использую команду ReportMemoryLeaksOnShutdown := True. Если дополнительный поток не использую, утечек нет.
procedure LoadProjectFromFile(AFileName: string);
var
fut: IFuture<TComponent>;
cmp: TComponent;
begin
AniIndic.Enabled := True;
AniIndic.Visible := True;
fut := TTask.Future<TComponent>(
function: TComponent
begin
Result := LoadFromFile(AFileName);
end
);
TTask.Run(
procedure
begin
fut.Start;
cmp := fut.Value;
{$REGION 'После загрузки в главном потоке'}
TThread.Synchronize(nil,
procedure
begin
AniIndic.Enabled := False;
AniIndic.Visible := False;
if Assigned(cmp) then
begin
if cmp is TCAMProject then
begin
fProject := cmp as TCAMProject;
// здесь всякие действия
if Assigned(OnFinishedLoadProject) then
begin
OnFinishedLoadProject(nil);
end;
end
end
end
)
{$ENDREGION}
end
);
end; -
Спасибо, Slym! Задача решена!
-
Здравствуйте!
Пишу алгоритм с параллельными вычислениями. Один из объектов является разделяемым ресурсом и хотелось бы его клонировать. Объект достаточно сложный и использует другие объекты. Возникла идея применения механизма сериализации/десериализации. Примерный код ниже.
function Cloning(RootObject: TComponent): TComponent;
var
MemStream: TMemoryStream;
begin
MemStream := TMemoryStream.Create;
try
MemStream.WriteComponent(RootObject);
MemStream.Position := 0;
Result := MemStream.ReadComponent(RootObject);
finally
MemStream.Free;
end;
end;
Данный код, однако, не дает нужного результата. Исходный компонент RootObject и Result, в итоге, ссылаются на одну и ту же область памяти. Может ли уважаемое сообщество предложить какие-то решения? -
Снимаю предыдущий вопрос. Можно проверить через обращение к MainThreadID.
-
Правильно ли я понимаю, что номер, который печатался в опубликованном фрагменте кода - это номер главного потока?
-
Да, после выноса TThread.CurrentThread.ThreadID.ToString выше Synchronize(), получил разные номера потоков. Спасибо!
-
Здравствуйте!
Имею следующий фрагмент кода:
fines: array of Extended;
TParallel.For(0, Pred(count),
procedure(index: Integer)
begin
fines[index] := CalculateFine(Index);
TThread.Synchronize(nil,
procedure
begin
Memo.Lines.Add('ThreadID = ' + TThread.CurrentThread.ThreadID.ToString);end);
end);
В логе получаю один и тот же номер ThreadID для всех значений index. Разве не должны быть созданы count потоков, каждый со своим ID?
-
Это интересно. Спасибо!
-
Вы имеете ввиду в режиме синхронизации пересылать в лог главного потока данные из дополнительного с указанием номера дополнительного потока?
-
Кто-нибудь юзал такую штуку: "параллельный отладчик Parnassus"? Если да, то какое мнение? И можно ли его получить и установить не имея активной подписки на обновления?
-
Вижу, что посты от 15-го года. Мне понадобился целочисленный TScrollBar сейчас и именно в FMX. Похоже, ничего не изменилось. Ползунок меняет значение не на целую величину, а на дробную. Нужно писать своего потомка для компонента или кто-нибудь знает более простое решение?
-
Здравствуйте! В OpenGL и DirectX есть возможность при работе с буфером глубины (z-буфер) выбирать различные варианты приоритета для конфликтующих пикселей, то есть таких, которые находятся в сцене на одинаковом расстоянии от наблюдателя. В OpenGL, например, использовалась команда glDepthFunc(GLenum func), в которую можно было передать константу для выбора одного из двух соперничающих пикселей. Имеется ли подобная команда в FMX?
-
Спасибо, OnePeople и krapotkin! С Application.ProcessMessages в главном потоке оба потока работают одинаково, что и требовалось.
-
Приложу, на всякий случай, проект
-
То есть внутри цикла ProgressBar1 не перерисовывается.
-
Я про этот код. Главный поток.
procedure TForm1.Button1Click(Sender: TObject);
begin
Test;
end;procedure TForm1.Test;
const
n = 200;
var
I: Integer;
begin
ProgressBar1.Min := 0;
ProgressBar1.Max := n - 1;
for I := 0 to n - 1 do
begin
ProgressBar1.Value := I;
sleep(10);
end;
end;Я нажимаю кнопку и ожидаю, что после ее нажатия ProgressBar1 постепенно, в цикле, будет заполняться. Но этого не происходит. После нажатия я вижу пустой ProgressBar1 и только спустя время 10*200, в конце цикла, вижу уже заполненный ProgressBar1. Постепенного заполнения ProgressBar не происходит.
Такой же процесс в дополнительном потоке, однако, работает корректно. Точнее, так как мне нужно.
-
Спасибо за ссылку! Полезно. Добавил в избранное.
Про синхронизацию я знаю, поэтому сам был удивлен, что запись напрямую в компонент из доп потока сработала.
Вот такой код, с синхронизацией, для второй кнопки тоже работает:
procedure TForm1.Button2Click(Sender: TObject);
begin
TTask.Run(
procedure
const
n = 200;
var
I: Integer;
begin
TThread.Synchronize(nil,
procedure
begin
ProgressBar1.Min := 0;
ProgressBar1.Max := n - 1;
end
);
for I := 0 to n - 1 do
begin
TThread.Synchronize(nil,
procedure
begin
ProgressBar1.Value := I;
end
);
sleep(10);
end;
end
);
end;Вопрос мой такой: почему точно также не работает код для основного потока (кнопка 1), то есть почему не видно постепенного заполнения ProgressBar в главном потоке?
-
Коллеги, здравствуйте!
Есть максимально простая задача: в длительном цикле необходимо так или иначе показывать пользователю номер текущей итерации. Делаю это с помощью ProgressBar. При этом если использую главный поток (кнопка 1), то результат вижу по окончании цикла, когда ProgressBar уже заполнен, а когда использую дополнительный поток (кнопка 2) - вижу постепенное заполнение ProgressBar, чего и пытаюсь добиться в главном потоке. Почему так? Такое ощущение, что от меня ускользает какой-то важный принцип использования FMX. Кто-нибудь может объяснить происходящее? Код ниже. Спасибо!
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
FMX.Controls.Presentation;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ProgressBar1: TProgressBar;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure Test;
public
{ Public declarations }
end;var
Form1: TForm1;implementation
uses
System.Threading;
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
begin
Test;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
TTask.Run(
Test
);
end;procedure TForm1.Button3Click(Sender: TObject);
begin
ProgressBar1.Value := 0;
end;procedure TForm1.Test;
const
n = 200;
var
I: Integer;
begin
ProgressBar1.Min := 0;
ProgressBar1.Max := n - 1;
for I := 0 to n - 1 do
begin
ProgressBar1.Value := I;
sleep(10);
end;
end;end.
-
Уважаемый Олег, спасибо!
-
Олег, не могли бы Вы рассказать, какими материалами (документация, книги, интернет-ресурсы и пр.) пользовались для 3D визуализации карданного вала?
-
-
Коллеги, здравствуйте! Прошу поделиться ссылками на работу с классом TVertexBuffer. Книгу Осипова читал, но информации для решения моих задач не нашел. Может есть что-то еще по 3D работе с Fire-Monkey? Спасибо!
Утечка памяти
в Отладка
Опубликовано
Применено так, как вы предложили. В методе FormClose. В тестовом примере оказывается
ThreadPoolStats.IdleWorkerThreadCount=3
и
ThreadPoolStats.WorkerThreadCount=3
Условие не выполняется, программа закрывается с утечкой.
Насколько я понял, ThreadPoolStats.IdleWorkerThreadCount хранит кол-во потоков, ожидающих завершения.
Если, например, изменить условие на
if ThreadPoolStats.IdleWorkerThreadCount>0
то приложение просто невозможно закрыть.