AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DEC onProgress-Ereignis bei mehreren Threads

Ein Thema von Luckie · begonnen am 9. Aug 2003 · letzter Beitrag vom 11. Aug 2003
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

DEC onProgress-Ereignis bei mehreren Threads

  Alt 9. Aug 2003, 18:36
Folgendes: In einer Liste habe ich verschiedene Dateien zum Verschlüsseln. Für jede Datei wird jetzt ein Thread mit BeginThread gestartet. In diesem Thread wird jetzt dynamisch die Cipher-Komponente erzeugt und dem OnProgress Ereignis eine Prozedur zugewiesen. In einer zweiten Spalte eines Listview soll nur der Fortschrit separat für jede Datei angezeigt werden. Wie teile ich OnProgress jetzt mit welche Spalte er aktualisieren soll?

Ich habe kein TTHread-Object, sondern arneite mit der Windows-API.

Schema:
Code:
procedure MyProgress;
begin
  Listview1.Items[x],Subitems[0].Text := y%;
end;

function Thread
begin
  TCipher.OnProgress := myProgress;
end;
Das "X" ist jetzt das Problem.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 9. Aug 2003, 19:08
Mein Lösungsversuch:

Ich vergebe beim Erstellen im Thread die Tag-Eigenschaft. In OnProgress ist sie aber immer 0.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 9. Aug 2003, 22:29
So ich habe es jetzt geschaft, aber nicht so richtig. Ich benutze jetzt ein TThread-Objekt.
Delphi-Quellcode:
procedure BlowFishThread.EncryptBlowFish;
var
  BlowFish: TCipherManager;
begin
  BlowFish := TCiphermanager.Create(nil);
  with BlowFish do
  begin
    try
      Algorithm := 'Blowfish';
      InitKey(FPW, nil);
      OnProgress := Progress;
      EncodeFile(FFilename, FFilename + '.encoded');
    except
      BlowFish.Free;
      FPosition := -1;
      exit;
    end;
  end;
  BlowFish.Free;
end;

procedure BlowFishThread.Progress;
begin
  FPosition := Trunc(100 / Maximal * Current);
  Synchronize(UpLV);
end;

procedure BlowFishThread.Execute;
var
  Header: TFileHeader;
begin
  EncryptBlowFish;
  with Header do
  begin
    HeaderSize := sizeof(TFileHeader);
    sVersion := VER;
    sAlgo := ALGO_BLOWFISH;
    KeySize := 0;
  end;
  Addheader(Header, Filename + '.encoded');
end;

procedure BlowFishThread.UPLV;
begin
  Form1.UpLV(FIndex, FPosition);
end;
Allerdings zählt er nur die letzte Datei hoch.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 10. Aug 2003, 00:15
So eine Konstruktion hilft auch nicht:
Delphi-Quellcode:
procedure BlowFishThread.Execute;
var
  Header: TFileHeader;
begin
  setlength(FIndexArray, length(FIndexArray)+1);
  FIndexArray[length(FIndexArray)-1] := FIndex;
  setlength(FPositionArray, length(FPositionArray)+1);
  EncryptBlowFish;
Delphi-Quellcode:
procedure BlowFishThread.Progress;
var
  i: Integer;
begin
  for i := 0 to length(FPositionArray)-1 do
  begin
     FPositionArray[i] := Trunc(100 / Maximal * Current);
  end;
  Synchronize(UpLV);
end;
Delphi-Quellcode:
procedure BlowFishThread.UPLV;
var
  i: Integer;
begin
  for i := 0 to length(FIndexArray)-1 do
  begin
    Form1.UpLV(FIndexArray[i], FPositionArray[i]);
    writeln(IntToStr(FIndexArray[i])+' / '+IntToStr(FPositionArray[i]));
    break;
  end;
end;
Ich habe jetzt mal das Projekt angehangen. Ob das sicher ist sei erst mal dahingestellt. benötigt wird das DEC von Hagen Reddmann.
Angehängte Dateien
Dateityp: zip filecrypter_3.x.zip (5,8 KB, 6x aufgerufen)
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 10. Aug 2003, 11:55
So Code etwas überarbeitet. Es geht aber immer noch nicht, so wie ich will.
Angehängte Dateien
Dateityp: zip filecrypter_3.x_177.zip (5,1 KB, 5x aufgerufen)
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#6

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 10. Aug 2003, 12:09
Hi Luckie,

sorry für die späte Antwort, aber es gibt auch mal einen Geburtstag zu feiern.

Also, es ist schon erschreckend wie du so schnell die Schwachstellen im DEC findest. OnProgress() ist ein globales Event das 1. nicht threadsafe ist und 2. global immer nur einen Verschlüsselungsprozess unterstützt.

D.h. mit OnProgress() wirst du das was du willst nie hinbekommen. Vergiss es also. Verzichte auf TCipherManager/THashManager, beides sind Komponenten die ich für die DAU's coden musste, es sind Drag&Design Hilfsmittel.


Nachfolgend zeige ich wie man jeden Stream mit Progress Funktionalität ausbauen kann. D.h. deine Progressbar sollte individuell zum Streaming sein, dann ist sie auch threadsafe. Desweiteren zeige ich wie man Verschlüsselt ohne TCipherManager, die Entschlüsselung bekommste damit selber hin.

Delphi-Quellcode:
type
  TStreamProgressAdapter = class(TStream)
  private
    FStream: TStream;
  protected
    procedure SetSize(NewSize: Longint); override;
  public
    constructor Create(AStream: TStream);
    destructor Destroy; override;
    function Read(var Buffer; Count: Longint): Longint; override;
    function Write(const Buffer; Count: Longint): Longint; override;
    function Seek(Offset: Longint; Origin: Word): Longint; override;

    procedure DoProgress(Writing: Boolean); virtual;
  end;

procedure TStreamProgressAdapter.SetSize(NewSize: Longint);
begin
  TStreamProgressAdapter(FStream).SetSize(NewSize);
end;

constructor TStreamProgressAdapter.Create(AStream: TStream);
begin
  inherited Create;
  FStream := AStream;
end;

destructor TStreamProgressAdapter.Destroy;
begin
  inherited Destroy;
  FStream.Free;
end;

function TStreamProgressAdapter.Read(var Buffer; Count: Longint): Longint;
begin
  Result := FStream.Read(Buffer, Count);
  DoProgress(False);
end;

function TStreamProgressAdapter.Write(const Buffer; Count: Longint): Longint;
begin
  Result := FStream.Write(Buffer, Count);
  DoProgress(False);
end;

function TStreamProgressAdapter.Seek(Offset: Longint; Origin: Word): Longint;
begin
  Result := FStream.Seek(Offset, Origin);
end;

procedure TStreamProgressAdapter.DoProgress(Writing: Boolean);
begin
  // hier deine Progress Funktionen einbauen
end;

procedure Encrypt(Stream: TStream; const Password: String; CipherClass: TCipherClass = nil); overload;
begin
  if CipherClass = nil then
    CipherClass := TCipher_Blowfish;
  with CipherClass.Create('', nil) do
  try
    Mode := cmCTS;
    InitKey(Password, nil);
    EncodeStream(Stream, Stream, -1);
  finally
    Free;
  end;
end;

procedure Encrypt(const FileName, Password: String; CipherClass: TCipherClass = nil); overload;
var
  Stream: TStream;
begin
  Stream := TStreamProgressAdapter.Create(TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive));
  try
    Encrypt(Stream, Password, CipherClass);
  finally
    Stream.Free;
  end;
end;

procedure TestC;
begin
  Encrypt('d:\test.bin', 'Test');
  Encrypt('d:\test.bin', 'Test', TCipher_Rijndael);
  Encrypt('d:\test.bin', 'Test', TCipherClass(DECClassByName('IDEA', TCipher)));
end;
Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 10. Aug 2003, 12:24
Danke. Dann habe ich es ja gerade im richtigen Moment wieder hervor geholt.

Wie komme ich in OnProgress an die Werte dran und wie weise ich das Ereignis einer Ver- / Entschlüsselung zu?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#8

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 10. Aug 2003, 12:38
Du redest jetzt von obigem TStreamProgressAdapter ?
Diese Klasse muß natürlich erweitert werden. Im .DoProgress kann man über FStream.Size und FStream.Position das Verhältniss ermittelt werden.
In meinem eigene Source habe ich dies allerdings über eigene Variablen gemacht. Also im Contructor FStream.Size zwischen gespeichert. Im .Seek() .Read() und .Write() zähle ich eine eigene FPosition mit. Im .DoProgress() kann ich nun die berechnete FSize und FPosition von TStreamProgressAdapter auswerten. Dies verhindert unnötige Repositionierungen wenn man mit FStream.Position und FStream.Size arbeitet. Intern wird nämlich über Seek() die Größe des Stream ermittelt.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 10. Aug 2003, 13:30
So. Ich habe das jetzt mal eingebaut noch ohne Threads nur zum Testen. Leider bin ich da auf ein paar Probleme gestossen.

Erst mal habe ich den von dir gepostet Code in eine Unit gesteckt und entsprechend erweitert. Du findest sie im Anhang.

Dann habe ich versucht den Code anzuwenden. Habe da aber wohl noch ein paar Verständnisschwierigkeiten.

Delphi-Quellcode:
procedure TForm1.btnOKClick(Sender: TObject);
var
  i: Integer;
  Filename: string;
  ProgressAdapter: TStreamProgressAdapter;
  FileStream: TFileStream;
begin
  for i := 0 to lvFiles.Items.Count - 1 do
  begin
    Filename := lvFiles.Items.Item[i].Caption;
    if lvFiles.Items.Item[i].SubItems[0] = 'unverschlüsseltthen
    begin
      FileStream := TFileStream.Create(Filename, fmOpenReadWrite);
      try
        ProgressAdapter := TStreamProgressAdapter.Create(FileStream);
        try
          Encrypt(FileStream, edtPW1.Text, TCipher_Rijndael); // 156
          lvFiles.Items.Item[i].SubItems[0] := FloatToStr(ProgressAdapter.Progress);
        finally
          {???}
        end;
      finally
        FreeAndNil(FileStream);
      end;
    end;
  end;
end;
Frage: Kann es so überhaupt funktionieren? Weil wenn ich in der Schleife den ProgressAdapter gleich wieder freigebe, dann war es das ja gewesen, deswegen die drei Dedektive (???) an dieser Stelle.

Probleme:
Zitat:
[Fehler] Unit1.pas(156): Undefinierter Bezeichner: 'TCipher_Rijndael'
Zitat:
[Fehler] Unit1.pas(156): Es gibt keine überladene Version von 'Encrypt', die man mit diesen Argumenten aufrufen kann
Angehängte Dateien
Dateityp: pas endecrypt.pas (2,7 KB, 4x aufgerufen)
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#10

Re: DEC onProgress-Ereignis bei mehreren Threads

  Alt 10. Aug 2003, 17:16
Einfacher, TProgressAdapter gibt den Stream den er kapselt selber frei. D.h. FileStream.Free ist in jedem Falle falsch.

Delphi-Quellcode:
ProgressAdapter := TStreamProgressAdapter.Create(TFileStream.Create(FileName, Mode));
try
  ProgressAdapter.Read();
  ProgressAdapter.Write();
finally
  ProgressAdapter.Free;
end;
D.h. der Stream den man einem TStreamProgressAdapter übergibt ist irrelevant und muß nicht mehr als variable gespeichert werden. Alle Stream-Funktionen laufen nur über den ProgressAdapter, er kapselt sozusagen vollständig ein anderes Stream Object. Der Vorteil: statt ihn nur für Progressbars zu nutzen kann er auch beim Lesen/Schreiben Prüfsummen berechnen, zusätzlich komprimieren und vwerschlüsseln. Dazu müssen nur die .Write() .Read() Methoden angepasst werden.

Gruß Hagen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 22:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz