2010-12-10 45 views
2

J'ai une question sur les filets et les commandes. J'ai fait un dialogue modal de synchronisation. Il y a trois barres de progression et deux légendes. Si l'application est ouverte pour la première fois, il ouvrira la boîte de dialogue de synchronisation et fera la mise à jour. Sur la méthode de dialogue Show(), je crée trois threads différents. Chaque thread contrôle le téléchargement des données, l'analyse XML et l'insertion de la base de données. Et puis montre les progrès sur la barre de progression. Tout décrit, fonctionne bien.Fenêtre de fermeture de la butée de fil

Maintenant le problème - Je veux fermer cette boîte de dialogue automatiquement lorsque tous les éléments sont téléchargés, analysés et insérés dans la base de données. J'ai essayé de vérifier si progressbar.position est égal à progressbar.max et j'ai essayé de vérifier si les threads sont terminés. Si je vais avec la barre de progression, la boîte de dialogue se ferme trop tôt et une barre de progression n'est pas totalement terminée. Si je vais avec le thread de contrôle, alors les barres de progression s'arrêtent au milieu du processus et c'est tout.

Peut-être que vous l'avez fait et dire à Delphi n00b, comment est la meilleure façon de le faire.

Merci à l'avance ...

Répondre

5

Pour cette chose simple, vous pouvez utiliser l'événement fil OnTerminate (qui se déroule dans le contexte du thread principal) juste pour décrémenter une variable « nombre thread » initialisé à 3 au fil moment de création.

Lorsque le nombre de threads atteint 0, vous pouvez fermer le formulaire en toute sécurité.

begin 
    //..thread creation, stuff 
    FThreadCount := 3; 
    DownloadThread.OnTerminate := DecThreadCount; 
    ParseThread.OnTerminate := DecThreadCount; 
    InsertThread.OnTerminate := DecThreadCount; 
    //resume threads and other stuff 
end; 

procedure TForm1.DecThreadCount(Sender: TObject); 
begin 
    Dec(FThreadCount); 
    if FThreadCount = 0 then 
    Close; 
end; 
+1

+1 C'est beaucoup plus simple que ma réponse "poster un message"! –

+0

Je vais essayer, est-ce ThreadDecCount un peu d'événement? – evilone

+0

@Evilone: ​​c'est un TNotifyEvent. – jachguate

1

Je reçois vos fils pour poster un message à la boîte de dialogue lorsqu'elles sont terminées. Une fois les trois messages reçus, vous pouvez fermer la boîte de dialogue.

+0

Je suis nouveau chez Delphi. Comment affichez-vous ces messages? Postmessage/Sendmessage? Pouvez-vous me montrer un exemple? – evilone

+0

@evilone Dans ce cas, vous pouvez appeler soit. Pour en savoir plus sur win32 de base, vous devriez lire le livre de Petzold. –

2

Utilisez-vous Windows Vista ou Windows 7? Microsoft a changé la façon dont les barres de progression fonctionnent dans Vista, de sorte que, au lieu de sauter immédiatement à la position indiquée, il glisse graduellement vers lui. Cela signifie que votre progression peut être terminée, mais la barre ne l'indique pas pendant une seconde ou deux, il semble donc que la boîte de dialogue est fermée avant d'avoir terminé, surtout si la barre a un petit nombre d'étapes de progression.

Il est un peu moche, mais vous pouvez contourner ce problème en utilisant une fonction d'assistance qui fait quelque chose comme ceci:

procedure UpdateProgressBar(bar: TProgressBar); 
begin 
    bar.StepIt; 
    bar.Max := bar.Max + 1; 
    bar.Max := bar.Max - 1; 
end; 

Cela permettra d'assurer qu'il saute immédiatement à la bonne position.

EDIT: Détails dans How do I make TProgressBar stop lagging?

+0

+1 @Mason Maintenant que vous dites cela, j'ai vu l'effet que vous décrivez. Cela est-il documenté où que vous sachiez ou avez-vous travaillé par expérience ?! –

+0

@David: J'ai appris cela en m'envoyant des infos sur StackOverflow. Ajout d'un lien dans l'édition. –