2017-05-15 3 views
-1

J'utilise TJclZipCompressArchive du JCL Jedi avec le 7zip.dll d'ajouter plusieurs fichiers à une archive ZIP comme ceci:L'utilisation de blocs TJclZipCompressArchive le thread principal VCL Delphi

arch := TJclZipCompressArchive.Create(_ZipFn); 
arch.OnProgress := HandleOnProgress; 
for i := 0 to Files.Count - 1 do begin 
    fn := Files[i]; 
    arch.AddFile(ExtractFileName(fn), fn); 
end; 
arch.Compress; 
arch.CheckOperationSuccess; 

(Ce code est appelé à le thread VCL principal.) Alors que cela fonctionne, j'ai un problème montrant la progression et en option permettant à l'utilisateur d'annuler l'opération. A cette fin, j'ai ajouté un gestionnaire OnProgress:

procedure Tf_ZipMeasurement.HandleOnProgress(Sender: TObject; const Value, MaxValue: Int64); 
begin 
    // originally this called Application.ProcessMessages 
    TThread.Synchronize(nil, SyncHandleProgress); 

    if FAborted then 
    TJclZipCompressArchive(Sender).CancelCurrentOperation := True; 
end; 

A l'origine, je simplement mis à jour l'interface utilisateur et a appelé Application.ProcessMessages. Cela n'a pas fonctionné, car le thread appelant cet événement n'est pas le thread VCL principal, donc je l'ai changé pour appeler TThread.Synchronize à la place.

Malheureusement, cela entraîne un blocage, car apparemment le thread principal est occupé à faire quelque chose dans le 7zip.dll. (Comme le documentation on TJclZipCompressArchive est inexistant, je devine ici.)

Pour autant que je le vois, pour que cela fonctionne, je devrais appeler arch.Compress dans un fil de fond, donc le fil principal est disponible pour effectuer le traitement des messages.

Est-ce que quelqu'un a une certaine expérience avec l'utilisation de TJclZipCompressArchive ou 7zip.dll? Est-ce la bonne façon de le faire? Ou y a-t-il une option meilleure/plus simple?

+0

La plupart du doc ​​jedi est par l'exemple. Voir ".. \ jcl \ examples \ windows \ compression \ archive \ ..". –

+0

Merci pour l'indice, mais malheureusement, cela ne répond pas à la question car l'exemple ne montre pas de progrès, mais se bloque pendant que la compression est en cours d'exécution. – dummzeuch

Répondre

1

Votre analyse est correcte. Si la bibliothèque ZIP appelle votre gestionnaire d'événements progress sur un thread différent, l'appel Synchronize à partir de ce thread est un blocage. Vous avez dit:

apparemment le thread principal est occupé à faire quelque chose dans le 7zip.dll

Eh bien, ce qu'il fait est ce que vous avez dit à faire! A savoir compresser l'archive. Étant donné que la bibliothèque ZIP n'est pas native à Delphi, elle ne va pas envoyer les demandes Synchronize.

La marche à suivre est d'appeler Compress à partir d'un thread de travail.