Trying to load 6900 + cards into a list view, works fine if I do it normally, which blocks my ui and hangs, but when I use the parallel programming library, it loads about the first 100 then gives me action violation.
Trying to load 6900 + cards into a list view, works fine if I do it normally, which blocks my ui and hangs, but when I use the parallel programming library, it loads about the first 100 then gives me action violation.
Heres my code :
procedure TForm1.Button2Click(Sender: TObject);
var
LoadTask : ITask;
begin
LoadTask := TTask.Create(procedure
begin
LoadAllCards;
end);
//Application.ProcessMessages;
LoadTask.Start;
end;
And code to load all the cards
procedure TForm1.LoadAllCards;
var
CardCount, i : integer;
path1,path2 : string;
begin
//AniIndicator1.Enabled := true;
//AniIndicator1.Visible := true;
path1 := 'E:\DevPro\pics' + Pathdelim;
//path1 := Tpath.GetDocumentsPath + Pathdelim + 'pics' + Pathdelim ;
//path1 := GetCurrentDir + Pathdelim + 'pics' + Pathdelim ;
//Path2 := Path1 + 'thumbnail' + Pathdelim;
Path2 := Path1;
SQLDataSet1.CommandText := 'SELECT * FROM texts';
//SQLDataSet1.CommandText := 'SELECT * FROM texts WHERE id=27551';
SQLDataSet1.Open;
CardCount := SQLDataSet1.RecordCount;
Text1.Text := inttostr(cardcount);
for I := 1 to CardCount do
begin
// Litem.Text := SQLDataset1.Fields[1].Text;
if I = 1 then
begin
Litem := Listview1.Items.Add;
Litem.Text :=SQLDataSet1.Fields[1].Text;
if FileExists(Path2 + SQLDataSet1.Fields[0].text + '.jpg') then
begin
Litem.Bitmap.LoadFromFile(Path2 + SQLDataSet1.Fields[0].text + '.jpg');
end
end
else
begin
SQLDataSet1.Next;
LItem := Listview1.Items.Add;
Litem.Text := SQLDataset1.FieldList[1].Text;
if FileExists(Path2 + SQLDataSet1.Fields[0].text + '.jpg') then
begin
Litem.Bitmap.LoadFromFile(Path2 + SQLDataSet1.Fields[0].text + '.jpg');
end;
Self.Caption := inttostr(cardcount);
end;
end;
//Showmessage(Inttostr(cardcount));
SQLDataSet1.Close;
//AniIndicator1.Enabled := false;
//AniIndicator1.Visible := false;
//Litem := ListView1.Items.Add;
end;
Heres my code :
procedure TForm1.Button2Click(Sender: TObject);
var
LoadTask : ITask;
begin
LoadTask := TTask.Create(procedure
begin
LoadAllCards;
end);
//Application.ProcessMessages;
LoadTask.Start;
end;
And code to load all the cards
procedure TForm1.LoadAllCards;
var
CardCount, i : integer;
path1,path2 : string;
begin
//AniIndicator1.Enabled := true;
//AniIndicator1.Visible := true;
path1 := 'E:\DevPro\pics' + Pathdelim;
//path1 := Tpath.GetDocumentsPath + Pathdelim + 'pics' + Pathdelim ;
//path1 := GetCurrentDir + Pathdelim + 'pics' + Pathdelim ;
//Path2 := Path1 + 'thumbnail' + Pathdelim;
Path2 := Path1;
SQLDataSet1.CommandText := 'SELECT * FROM texts';
//SQLDataSet1.CommandText := 'SELECT * FROM texts WHERE id=27551';
SQLDataSet1.Open;
CardCount := SQLDataSet1.RecordCount;
Text1.Text := inttostr(cardcount);
for I := 1 to CardCount do
begin
// Litem.Text := SQLDataset1.Fields[1].Text;
if I = 1 then
begin
Litem := Listview1.Items.Add;
Litem.Text :=SQLDataSet1.Fields[1].Text;
if FileExists(Path2 + SQLDataSet1.Fields[0].text + '.jpg') then
begin
Litem.Bitmap.LoadFromFile(Path2 + SQLDataSet1.Fields[0].text + '.jpg');
end
end
else
begin
SQLDataSet1.Next;
LItem := Listview1.Items.Add;
Litem.Text := SQLDataset1.FieldList[1].Text;
if FileExists(Path2 + SQLDataSet1.Fields[0].text + '.jpg') then
begin
Litem.Bitmap.LoadFromFile(Path2 + SQLDataSet1.Fields[0].text + '.jpg');
end;
Self.Caption := inttostr(cardcount);
end;
end;
//Showmessage(Inttostr(cardcount));
SQLDataSet1.Close;
//AniIndicator1.Enabled := false;
//AniIndicator1.Visible := false;
//Litem := ListView1.Items.Add;
end;
Don't mix UI and background thread code. UI is owned by the main thread. Update the UI when your background is finished loading.
ReplyDeleteOn what line(s) does it AV?
ReplyDeleteIt is common knowledge not to access the VCL on a different thread to the main thread, so adding items to the List View and changing the form's caption is a no-no. TThread.Queue or TThread.Synchronize should be used.
Thanks guys, What I realised is that when the 6900 cards are loaded, 1gm ram is used, so instead I made it load cards on request and seperated the UI code to the procedure code
ReplyDelete