Delphi: форма становится замороженной при назначении строк в потоке - PullRequest
2 голосов
/ 18 июля 2011

Код ниже находится в потоке.

Tf1 := TFileStream.Create(LogsPath,fmOpenRead or fmShareDenyNone);
...
str:=TStringList.Create;
str.LoadFromStream(tf1);
...
SynEditLog.Lines.Assign(str); // I do this with Synchronize

В текстовом документе 30 000 строк.

Форма останавливается при назначении этих строк SynEdit.

Если загружать строку за строкой, это занимает у меня 40 секунд ... Если использовать Назначение - 8 секунд

Как предотвратить состояние этой формы?

Спасибо !!!

Ответы [ 2 ]

2 голосов
/ 18 июля 2011

Я не думаю, что Application.ProcessMessages здесь вообще поможет, так как вся работа происходит за один вызов Assign.

Есть ли у SynEditLog методы BeginUpdate / EndUpdate? Я бы использовал их и посмотрел, как у тебя дела. Например:

SynEditLog.BeginUpdate;
try
  SynEditLog.Lines.Assign(str);
finally
  SynEditLog.EndUpdate;
end;

В ответ на это не работает

Вам нужно будет разбить присвоение списка строк свойству Lines. Примерно так:

var
  LIndex: integer; 
begin
  SynEditLog.BeginUpdate;
  try
    //added: set the capacity before adding all the strings.
    SynEditLog.Lines.Capacity := str.Capacity;
    for LIndex := 0 to str.Count - 1 do
    begin
      SynEditLog.Lines.Add(str[LIndex]);
      if LIndex mod 100 = 0 then
        Application.ProcessMessages;
    end;
  finally
    SynEditLog.EndUpdate;
  end;
end;

(примечание: код, введенный непосредственно в браузер, может не скомпилироваться)

Если это слишком медленно, попробуйте увеличить LIndex mod 100 = 0 до чего-то большего, например, 1000 или даже 5000.

N @

1 голос
/ 18 июля 2011

Форма зависает, потому что вы используете поток GUI, чтобы добавить 30 000 строк в свой элемент управления, что, естественно, занимает некоторое время.В течение этого времени графический интерфейс не может обновляться, поскольку вы используете его поток, поэтому он выглядит замороженным.

Одним из способов решения этой проблемы является добавление нескольких строк (или только одной) за раз, имежду каждым добавлением обновляйте графический интерфейс (вызывая Application.ProcessMessages (спасибо, Горди)).

...