Multithreading 在TMemo中添加多行时发生访问冲突
这是我在第一只火猴出现时第一次遇到的老问题。现在,即使使用XE5,也一样。我不能用TMemo做任何事情,除非每一行都添加了足够的延时 这个问题发生在有很多控件的重窗体上。如果行足够长,可以被包装并包含特殊字符,那么这种可能性就会增加。如果一个字符串包含换行符,那么它几乎总是被提升 在只包含备忘录和填充线程的表单中执行同样的操作不会产生任何AVs,我认为其他地方一定有问题 AV源于TTextSettings、TTextLayout、TText等 传奇 TAgStringList:从TStringlist派生的类,具有日志记录、字节转换和锁定支持 FLogMemo:视觉TMemo FDisplayReq:将日志行添加到FLogMemo中的条件 BeignRead:TMREWSync.BeginRead的内联方法 EndRead:TMREWync.EndRead的内联方法 日志法 日志线程方法Multithreading 在TMemo中添加多行时发生访问冲突,multithreading,delphi,logging,firemonkey,delphi-xe5,Multithreading,Delphi,Logging,Firemonkey,Delphi Xe5,这是我在第一只火猴出现时第一次遇到的老问题。现在,即使使用XE5,也一样。我不能用TMemo做任何事情,除非每一行都添加了足够的延时 这个问题发生在有很多控件的重窗体上。如果行足够长,可以被包装并包含特殊字符,那么这种可能性就会增加。如果一个字符串包含换行符,那么它几乎总是被提升 在只包含备忘录和填充线程的表单中执行同样的操作不会产生任何AVs,我认为其他地方一定有问题 AV源于TTextSettings、TTextLayout、TText等 传奇 TAgStringList:从TStringl
过程TAgStringList.LogManager;
变量
一:民族性;
EndIndex:nativent;
开始
开始;
EndIndex:=GetCount-1;
如果FLogManager.Tag
必须在UI线程上执行对UI控件的所有访问。您需要将UI访问代码排队或同步到主UI线程上 你能给我举个小例子说明我是如何做到的吗?BeginUpdate和EndUpdate之间有一个“for”,根据Log方法,至少要添加两行。线程也会每秒迭代一次,所以中间总是有10-20行。对不起,没有发现循环的起始点是stringlist中的列表而不是FLogmemoI不想再给出一个转移到主线程的例子。你一定看到了。这里有无数的例子。许多都是由德尔福提供的。如果你努力的话,一定能找到。
procedure TAgStringList.Log
( const APrefixes : Array of String;
const ALogs : Array of String;
const AException : Exception = nil );
var
I : NativeInt;
LogString : String;
begin
LogString := Format ( '[%s]', [FormatDateTime ( 'hh:mm:ss.zzz', Time )] );
for I := 0 to Length ( APrefixes ) - 1 do
LogString := Format ( '%s[%s]', [LogString, APrefixes [I]] );
if Assigned ( AException ) then
LogString := Format ( '%s[%s]', [LogString, AException.ClassName] );
if FDisplayReq then
FLogMemo.Lines.Add ( LogString );
Add ( LogString );
for I := 0 to Length ( ALogs ) - 1 do
begin
if FDisplayReq then
FLogMemo.Lines.Add ( ALogs [I] );
Add ( ALogs [I] );
end;
if Assigned ( AException ) then
begin
if FDisplayReq then
FLogMemo.Lines.Add ( AException.Message );
Add ( AException.Message );
Add ( '' );
end
else
Add ( '' );
end;
procedure TAgStringList.LogManager;
var
I : NativeInt;
EndIndex : NativeInt;
begin
BeginRead;
EndIndex := GetCount - 1;
if FLogManager.Tag < EndIndex then
begin
if Assigned ( FLogMemo ) then
begin
FLogMemo.BeginUpdate;
for I := FLogManager.Tag to EndIndex do
FLogMemo.Lines.Add ( Strings [I] );
FLogMemo.EndUpdate;
FLogManager.Tag := GetCount;
end;
SaveToFile ( FLogFileName );
end;
EndRead;
end;