Multithreading Delphi:窗体在线程中分配字符串时被冻结

Multithreading Delphi:窗体在线程中分配字符串时被冻结,multithreading,forms,delphi,freeze,Multithreading,Forms,Delphi,Freeze,下面的代码位于线程中 Tf1 := TFileStream.Create(LogsPath,fmOpenRead or fmShareDenyNone); ... str:=TStringList.Create; str.LoadFromStream(tf1); ... SynEditLog.Lines.Assign(str); // I do this with Synchronize 文本文档中有30000个字符串 将这些字符串指定给SynEdit时,表单将被冻结 如果一个字符串一个字符串

下面的代码位于线程中

Tf1 := TFileStream.Create(LogsPath,fmOpenRead or fmShareDenyNone);
...
str:=TStringList.Create;
str.LoadFromStream(tf1);
...
SynEditLog.Lines.Assign(str); // I do this with Synchronize
文本文档中有30000个字符串

将这些字符串指定给SynEdit时,表单将被冻结

如果一个字符串一个字符串加载,我需要40秒。。。如果要使用分配-8秒

如何防止此表单的状态


谢谢

表单是冻结的,因为您正在使用GUI线程向控件添加30000行,这自然需要一段时间。在此期间,GUI无法更新,因为您正在使用它的线程,所以它看起来是冻结的


解决这个问题的一种方法是一次添加几行(或仅一行),并在每次添加之间更新GUI(通过调用
Application.ProcessMessages
(感谢gordy))。

我认为
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


没有帮助!我将ProcessMessages放入SynEdit的SpecialLineColors事件中,在其中绘制线条。更确切地说,SynEdit是在一个框架上的。你不能通过ProcessMessages调用来解决这个问题。那一行要花很多时间,你不能打断它。您必须将加载放到后台线程中。@maxfax您必须手动分解这些行,因为Loren是正确的,这就是那一行。手动,我的意思是把它们放在一个容器中,迭代它,一次添加一个,中间调用
ProcessMessages
,不管你想要多少。这是不可能的,如果这样做,那么我需要1分钟来添加所有30000个字符串。然后,您可能需要选择是让您的应用程序在密集计算期间冻结,还是让它们平滑添加,但需要一段时间。它已开始更新/结束更新。但这也没用。我不能使用循环。如果使用这种方法添加字符串,我大约需要1分钟!!!分配-8秒。首先尝试设置Lines属性的容量。我已经更新了我的示例。有趣的是存在差异,这就是所有的
TStrings.Assign
does.@maxfax在加载文件时没有与用户交互是可以的。当你的应用程序处于那种状态时,用户可以安全地做什么?为什么要先加载到字符串列表中?为什么不直接加载到控制中?我打赌TMemo可以在8秒内加载30000行。我在那里做了一些操作。没关系。我查过了。如果要直接做,请同时进行。