Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在TMemo中添加多行时发生访问冲突_Multithreading_Delphi_Logging_Firemonkey_Delphi Xe5 - Fatal编程技术网

Multithreading 在TMemo中添加多行时发生访问冲突

Multithreading 在TMemo中添加多行时发生访问冲突,multithreading,delphi,logging,firemonkey,delphi-xe5,Multithreading,Delphi,Logging,Firemonkey,Delphi Xe5,这是我在第一只火猴出现时第一次遇到的老问题。现在,即使使用XE5,也一样。我不能用TMemo做任何事情,除非每一行都添加了足够的延时 这个问题发生在有很多控件的重窗体上。如果行足够长,可以被包装并包含特殊字符,那么这种可能性就会增加。如果一个字符串包含换行符,那么它几乎总是被提升 在只包含备忘录和填充线程的表单中执行同样的操作不会产生任何AVs,我认为其他地方一定有问题 AV源于TTextSettings、TTextLayout、TText等 传奇 TAgStringList:从TStringl

这是我在第一只火猴出现时第一次遇到的老问题。现在,即使使用XE5,也一样。我不能用TMemo做任何事情,除非每一行都添加了足够的延时

这个问题发生在有很多控件的重窗体上。如果行足够长,可以被包装并包含特殊字符,那么这种可能性就会增加。如果一个字符串包含换行符,那么它几乎总是被提升

在只包含备忘录和填充线程的表单中执行同样的操作不会产生任何AVs,我认为其他地方一定有问题

AV源于TTextSettings、TTextLayout、TText等

传奇 TAgStringList:从TStringlist派生的类,具有日志记录、字节转换和锁定支持

FLogMemo:视觉TMemo

FDisplayReq:将日志行添加到FLogMemo中的条件

BeignRead:TMREWSync.BeginRead的内联方法

EndRead:TMREWync.EndRead的内联方法

日志法 日志线程方法
过程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;