2011-07-18 57 views
2

以下代碼位於線程中。Delphi:在線程中分配字符串時窗體變爲凍結

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秒...如果使用Assign - 8秒。

如何防止此表單的狀態?

謝謝!

+0

爲什麼首先加載到字符串列表中?爲什麼不直接加載控制?我敢打賭,TMemo可以在8秒內裝載30 000行。 –

+0

我在那裏做一些操作。不要緊。我檢查過。如果直接做 - 同一時間。 – maxfax

回答

2

我不認爲Application.ProcessMessages會在這裏幫助,因爲所有的工作都發生在Assign的一次調用中。

請問SynEditLogBeginUpdate/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 @

+0

它有BeginUpdate/EndUpdate。但它也沒有幫助。 – maxfax

+0

我不能使用循環。如果使用這種方法添加字符串,我需要1分鐘左右!分配 - 8秒。 – maxfax

+0

嘗試先設置Lines屬性的容量。我已更新我的示例。 – Nat

1

表單凍結,因爲您使用GUI線程向您的控件添加30,000行,這自然需要一段時間。在此期間,GUI無法更新,因爲您正在使用其線程,因此它看起來是凍結的。

解決此問題的一種方法是每次只添加幾行(或者只添加一行),並在每次添加之間更新GUI(通過調用Application.ProcessMessages(感謝gordy))。

+1

並通過調用Application.ProcessMessages – gordy

+0

來更新GUI沒有幫助!我把ProcessMessages放到一個SynEdit的SpecialLineColors事件中,在那裏我畫線。更確切地說SynEdit是在一個框架上。 – maxfax

+0

您無法通過ProcessMessages調用來解決此問題。那* ONE *行將花費一些時間,你不能分解它。您必須將負載放入後臺線程中。 –