AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Reicht Syncronize oder besser Syncronize + CriticalSection ?
Thema durchsuchen
Ansicht
Themen-Optionen

Reicht Syncronize oder besser Syncronize + CriticalSection ?

Ein Thema von DataCool · begonnen am 11. Aug 2004 · letzter Beitrag vom 27. Mär 2006
Antwort Antwort
Meta777

Registriert seit: 8. Sep 2004
Ort: Magdeburg
248 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Re: Reicht Syncronize oder besser Syncronize + CriticalSecti

  Alt 27. Mär 2006, 22:31
Hi DPler,

Ich habe ein ähnliches Problem.
Ich habe eine Log-Klasse welche auch threadsicher FTP aktionen loggen soll.
Die Klasse wird aber auch in diversen anderen Programmen benutzt.
Das scheint auch ganz gut zu funktionieren aber manchmal bekomme ich AVs
und ich weiß nicht genau ob es nun an der Klasse liegt?
Ich habe den verdacht das es evtl. Probleme mit Synchronize und
Dateizugriffen gibt? Oder ist das TIdSync, von dem TLog abgeleitet ist,
nicht die optimale Wahl?
Das der Logeintrag auch an das Memo des Protokoll-Forms angehängt wird
sollte doch durch Synchronize kein Problem sein, oder?

Ein Logeintrag wird über die Klassenproceduren TLog.Add() hinzugefügt.

Bin für generelle oder konkrete Hinweise dankbar.

Gottes Segen

Nun etwas Source:
Delphi-Quellcode:
type
  TDaPrtData = record
    Typ: TDaPrtMsgType;
    Msg: String;
    Cls: ShortString;
    Code: Integer;
    SQL: String;
    Details: String;
    DoId: Integer;
    ConfigId: Integer;
  end;

//This is based on the example found in the indy newsgroup
  TLog = class(TIdSync)
  protected
    FPrtData: TDaPrtData;
    procedure DoSynchronize; override;
    constructor Create(const APrtData: TDaPrtData);
  public
    class procedure Add(const APrtData: TDaPrtData); overload;
    class procedure Add(const AStr: String); overload;
  end;




//---------------------------------------------------//
//------------------------ TLog ---------------------//

constructor TLog.Create(const APrtData: TDaPrtData);
begin
  FPrtData := APrtData;
  inherited Create;
end;

procedure TLog.DoSynchronize;
var
  lFileStream: TFileStream;
  lMode: Word;
  lString: String;

  procedure TruncateStream;
  var
    Buffer: TMemoryStream;
    c, n1, n2, Len: Int64;
  begin
// QueryPerformanceFrequency(c);
// QueryPerformanceCounter(n1);
    Buffer := TMemoryStream.Create;
    try
      Buffer.Size := konPrtLowFileSize;
      lFileStream.Position := lFileStream.Position - konPrtLowFileSize;
      Len := Buffer.CopyFrom(lFileStream, konPrtLowFileSize);
      Buffer.Position := 0;
      lFileStream.Position := 0;
//TODO 1: Alternative. Works but sure slow??
      lFileStream.Size := 0;
      lFileStream.Size := konPrtLowFileSize;

      lFileStream.Position := 0;
      lFileStream.CopyFrom(Buffer, Len);
      QueryPerformanceCounter(n2);
      OutputDebugString(PChar(FloatToStr(n2-n1/c, formatSet)));
// TLog.Add(FloatToStr(n2-n1/c, formatSet));//geht nicht - AV!?!¿!?
    finally
      Buffer.Free;
    end;
  end;

  procedure LogToScreen;
  begin
    try
      frmProt.memLog.Lines.BeginUpdate;
      if frmProt.memLog.Lines.Count > frmProt.PrtOptions.PrtSize then begin
        while frmProt.memLog.Lines.Count > frmProt.PrtOptions.PrtSize-50 do//Cut off 50 Lines
          frmProt.memLog.Lines.Delete(0);
        frmProt.memLog.Lines.Add('$$$'+konPrtColDel+DateTimeToStr(Now, formatSet)+'LOG TRUNCATE'+konPrtLineDel);
      end;
      frmProt.memLog.Lines.Add(lString);
// if True{Optionen_Form.miscAutoScrollLog }then begin
        frmProt.memLog.Perform(EM_LINESCROLL, 0, frmProt.memLog.Lines.Count);
// end;
      frmProt.memLog.Lines.EndUpdate;
    except
      frmProt.PrtOptions.AbledPrtModes := frmProt.PrtOptions.AbledPrtModes -
        [pmScreen];
    end;
  end;//procedure LogToScreen

  procedure LogToFile;
  begin
    try
      if FileExists(frmProt.PrtOptions.PrtFileName) then
        lMode := fmOpenReadWrite or fmShareDenyWrite
      else
        lMode := fmCreate;
      lFileStream := TFileStream.Create(frmProt.PrtOptions.PrtFileName, lMode);
      try
        if lMode <> fmCreate then
          lFileStream.Seek(0, soFromEnd);
        lFileStream.Write(LString[1], Length(lString));
        lFileStream.Write(sLineBreak, Length(sLineBreak)); // <-- sLineBreak is defined by VCL
        if lFileStream.Size > konPrtHighFileSize then begin
          TruncateStream;
        end;
      finally
        lFileStream.Free;
      end;
    except
      frmProt.PrtOptions.AbledPrtModes := frmProt.PrtOptions.AbledPrtModes -
        [pmFile];
    end
  end;//procedure LogToFile
begin
  lString := '';
  case FPrtData.Typ of
    pmtInformation: lString := '###' + konPrtColDel;
    pmtConfirmation: lString := '???' + konPrtColDel;
    pmtWarning: lString := 'x!x' + konPrtColDel;
    pmtError: lString := 'XXX' + konPrtColDel;
  end;
                       //Using a formatSetting var it is thread save.
  lString := lString + DateTimeToStr(Now, formatSet) + konPrtColDel +
    FPrtData.Msg + konPrtColDel + FPrtData.Cls + konPrtColDel + FPrtData.SQL + konPrtColDel +
    FPrtData.Details + konPrtColDel + IntToStr(FPrtData.DoId) + konPrtColDel +
    IntToStr(FPrtData.ConfigId) +
    konPrtLineDel;//2006_01_29 We need a Line-Delimiter cause of multiline prt entries!
  case frmProt.PrtOptions.PrtUsage of
    cbChecked: begin
      if pmScreen in frmProt.PrtOptions.AbledPrtModes then
        LogToScreen;
      if pmFile in frmProt.PrtOptions.AbledPrtModes then
        LogToFile;
    end;
    cbGrayed: begin
      if pmScreen in frmProt.PrtOptions.AbledPrtModes then
        LogToScreen;
    end;
    cbUnchecked:;//nothing
  end;//case cbUseProt.State
end;

class procedure TLog.Add(const APrtData: TDaPrtData);
begin
  with TLog.Create(APrtData) do try
    Synchronize;
  finally
    Free;
  end;
end;

class procedure TLog.Add(const AStr: String);
var
  LPrtData: TDaPrtData;
begin
  FillChar(LPrtData, SizeOf(LPrtData), #0);
  LPrtData.Msg := AStr;
  with TLog.Create(LPrtData) do try
    Synchronize;
  finally
    Free;
  end;
end;

//------------------------ TLog ---------------------//
//---------------------------------------------------//
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz