Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Message d'attente

19 réponses
Avatar
Stephane TUET
Bonjour

J'essaie depuis un bon moment maintenant et sans succés de réaliser un
message d'attente pendant un traitement (en fait, un appel à un Web Service
en mode synchrone). Le but est que le message apparaisse lorsque le temps
d'attente devient trop long... Comme j'ai également une image Gif animée sur
cette form, je suppose qu'il faut que je crée un nouveau Thread pour que
l'animation marche correctement et pour gérer l'ouverture retardée.

J'ai bien commencé à écrire quelques lignes de code, mais ça ne fonctionne
par comme je veux (en général je n'ai rien du tout qui s'affiche :-) )

Dans un module j'ai les déclarations suivantes :
Private frm_wait As New frm_wait 'la fenêtre d'attente

Private WithEvents TimerWait As New Timer

Private Thread As New Threading.Thread(AddressOf DebutThreadAttente)


Dans ma fenêtre où il y a l'appel au service web j'ai qq chose du style :

DebutAttente()
try
'Appel du service web
catch
'gestion d'erreur
end try
FinAttente()


Et mes procédures sont les suivantes :

Public Sub DebutAttente()

TimerWait.Interval = K_TIMER_WAIT 'la variable définie en ms pour le
temps d'attente avant affichage de la fenêtre

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub



Avec cela je voulais réaliser uniquement un Show/Hide de la fenêtre
d'attente avant/après chacun des traitements mais ça ne marche pas...
J'avoue que je suis bien perdu avec ce thread. Si quelqu'un pouvait
m'indiquer une piste pour réaliser cela...

Merci d'avance

Steph

10 réponses

1 2
Avatar
AlexC
d'après le code que tu donne :

Tu execute DebutAttente qui lance un timer...
Tu lances Ton service web qui traite sa tache ....
Quand il a finit sa tache tu execute FinAttente.

Tu as définit une intervalle pour le timer ( c'est un exemple ) 10ms
Donc au bout de 10ms le timer va s'arreter et lancer un autre Thread (
indépendant du service Web )
Ce Thread affiche la fenetre et s'arretes ( je suppose que frm_wait est
globale )

Ma question est :

Le lancement du service web se fait - il via un autre thread ? ou bloque t-
il le thread principal ?
si il se fait via un thread à part, il est normal que la fenetre se referme.

"Stephane TUET" a écrit dans le message de news:
OgJHmX$
Bonjour

J'essaie depuis un bon moment maintenant et sans succés de réaliser un
message d'attente pendant un traitement (en fait, un appel à un Web
Service en mode synchrone). Le but est que le message apparaisse lorsque
le temps d'attente devient trop long... Comme j'ai également une image Gif
animée sur cette form, je suppose qu'il faut que je crée un nouveau Thread
pour que l'animation marche correctement et pour gérer l'ouverture
retardée.

J'ai bien commencé à écrire quelques lignes de code, mais ça ne fonctionne
par comme je veux (en général je n'ai rien du tout qui s'affiche :-) )

Dans un module j'ai les déclarations suivantes :
Private frm_wait As New frm_wait 'la fenêtre d'attente

Private WithEvents TimerWait As New Timer

Private Thread As New Threading.Thread(AddressOf DebutThreadAttente)


Dans ma fenêtre où il y a l'appel au service web j'ai qq chose du style :

DebutAttente()
try
'Appel du service web
catch
'gestion d'erreur
end try
FinAttente()


Et mes procédures sont les suivantes :

Public Sub DebutAttente()

TimerWait.Interval = K_TIMER_WAIT 'la variable définie en ms pour le
temps d'attente avant affichage de la fenêtre

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub



Avec cela je voulais réaliser uniquement un Show/Hide de la fenêtre
d'attente avant/après chacun des traitements mais ça ne marche pas...
J'avoue que je suis bien perdu avec ce thread. Si quelqu'un pouvait
m'indiquer une piste pour réaliser cela...

Merci d'avance

Steph



Avatar
Stephane TUET
Merci pour ta réponse et tu as bien compris ce que j'ai essayé de faire (et
j'en suis content, au moins même si mon code ne marche pas, il a été compris
:-) ). frm_wait est bien défini en global puisqu'il peut être appelé à
divers endroit dans mon application (je compte le faire à chaque appel d'un
service web).

L'appel du service web lui est réalisé dans le thread principal qui se
trouve donc bloqué.

J'ai également essayé de déplacé le lancement du timer comme ceci :

Public Sub DebutAttente()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

TimerWait.Interval = K_TIMER_WAIT

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub


Mais j'ai l'impression de ne pouvoir lancer le thread qu'une seule fois, au
deuxième appel à DebutAttente, j'ai un plantage...

Merci de ton aide.

Steph


"AlexC" <(@Anti-Spam)#(@Anti-Spam)#> a écrit
dans le message de news: uupRlv$
d'après le code que tu donne :

Tu execute DebutAttente qui lance un timer...
Tu lances Ton service web qui traite sa tache ....
Quand il a finit sa tache tu execute FinAttente.

Tu as définit une intervalle pour le timer ( c'est un exemple ) 10ms
Donc au bout de 10ms le timer va s'arreter et lancer un autre Thread (
indépendant du service Web )
Ce Thread affiche la fenetre et s'arretes ( je suppose que frm_wait est
globale )

Ma question est :

Le lancement du service web se fait - il via un autre thread ? ou bloque
t- il le thread principal ?
si il se fait via un thread à part, il est normal que la fenetre se
referme.

"Stephane TUET" a écrit dans le message de news:
OgJHmX$
Bonjour

J'essaie depuis un bon moment maintenant et sans succés de réaliser un
message d'attente pendant un traitement (en fait, un appel à un Web
Service en mode synchrone). Le but est que le message apparaisse lorsque
le temps d'attente devient trop long... Comme j'ai également une image
Gif animée sur cette form, je suppose qu'il faut que je crée un nouveau
Thread pour que l'animation marche correctement et pour gérer l'ouverture
retardée.

J'ai bien commencé à écrire quelques lignes de code, mais ça ne
fonctionne par comme je veux (en général je n'ai rien du tout qui
s'affiche :-) )

Dans un module j'ai les déclarations suivantes :
Private frm_wait As New frm_wait 'la fenêtre d'attente

Private WithEvents TimerWait As New Timer

Private Thread As New Threading.Thread(AddressOf DebutThreadAttente)


Dans ma fenêtre où il y a l'appel au service web j'ai qq chose du style :

DebutAttente()
try
'Appel du service web
catch
'gestion d'erreur
end try
FinAttente()


Et mes procédures sont les suivantes :

Public Sub DebutAttente()

TimerWait.Interval = K_TIMER_WAIT 'la variable définie en ms pour
le temps d'attente avant affichage de la fenêtre

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub



Avec cela je voulais réaliser uniquement un Show/Hide de la fenêtre
d'attente avant/après chacun des traitements mais ça ne marche pas...
J'avoue que je suis bien perdu avec ce thread. Si quelqu'un pouvait
m'indiquer une piste pour réaliser cela...

Merci d'avance

Steph







Avatar
AlexC
Le code etait pas compiqué mais j'aime bien etre sur du contexte pour
pouvoir répondre :)

J'ai refait le code et j'avoue que là ... no sé :)
la fenetre s'ouvre mais se referme aussitot ...
cela aurait ete logique si le code repassait par la methode Hide mais ce
n'est pas le cas
ou encore si la frm_wait avait été déclarée en locale et qu'à la sortie du
thread elle avait été détruite ..

je continue à regarder ..

"Stephane TUET" a écrit dans le message de news:
Oj%23M22$
Merci pour ta réponse et tu as bien compris ce que j'ai essayé de faire
(et j'en suis content, au moins même si mon code ne marche pas, il a été
compris :-) ). frm_wait est bien défini en global puisqu'il peut être
appelé à divers endroit dans mon application (je compte le faire à chaque
appel d'un service web).

L'appel du service web lui est réalisé dans le thread principal qui se
trouve donc bloqué.

J'ai également essayé de déplacé le lancement du timer comme ceci :

Public Sub DebutAttente()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

TimerWait.Interval = K_TIMER_WAIT

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub


Mais j'ai l'impression de ne pouvoir lancer le thread qu'une seule fois,
au deuxième appel à DebutAttente, j'ai un plantage...

Merci de ton aide.

Steph


"AlexC" <(@Anti-Spam)#(@Anti-Spam)#> a écrit
dans le message de news: uupRlv$
d'après le code que tu donne :

Tu execute DebutAttente qui lance un timer...
Tu lances Ton service web qui traite sa tache ....
Quand il a finit sa tache tu execute FinAttente.

Tu as définit une intervalle pour le timer ( c'est un exemple ) 10ms
Donc au bout de 10ms le timer va s'arreter et lancer un autre Thread (
indépendant du service Web )
Ce Thread affiche la fenetre et s'arretes ( je suppose que frm_wait est
globale )

Ma question est :

Le lancement du service web se fait - il via un autre thread ? ou bloque
t- il le thread principal ?
si il se fait via un thread à part, il est normal que la fenetre se
referme.

"Stephane TUET" a écrit dans le message de news:
OgJHmX$
Bonjour

J'essaie depuis un bon moment maintenant et sans succés de réaliser
un message d'attente pendant un traitement (en fait, un appel à un Web
Service en mode synchrone). Le but est que le message apparaisse lorsque
le temps d'attente devient trop long... Comme j'ai également une image
Gif animée sur cette form, je suppose qu'il faut que je crée un nouveau
Thread pour que l'animation marche correctement et pour gérer
l'ouverture retardée.

J'ai bien commencé à écrire quelques lignes de code, mais ça ne
fonctionne par comme je veux (en général je n'ai rien du tout qui
s'affiche :-) )

Dans un module j'ai les déclarations suivantes :
Private frm_wait As New frm_wait 'la fenêtre d'attente

Private WithEvents TimerWait As New Timer

Private Thread As New Threading.Thread(AddressOf DebutThreadAttente)


Dans ma fenêtre où il y a l'appel au service web j'ai qq chose du style
:

DebutAttente()
try
'Appel du service web
catch
'gestion d'erreur
end try
FinAttente()


Et mes procédures sont les suivantes :

Public Sub DebutAttente()

TimerWait.Interval = K_TIMER_WAIT 'la variable définie en ms pour
le temps d'attente avant affichage de la fenêtre

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub



Avec cela je voulais réaliser uniquement un Show/Hide de la fenêtre
d'attente avant/après chacun des traitements mais ça ne marche pas...
J'avoue que je suis bien perdu avec ce thread. Si quelqu'un pouvait
m'indiquer une piste pour réaliser cela...

Merci d'avance

Steph











Avatar
AlexC
J'ai trouvé, mais je ne comprends pas pourquoi ...

Il suffit d'enlever le Thread "DebutThreadAttente"
et de remplacer dans le gestionnaire d'évènemement du timer le Thread.start
par
frm_wait.show et ca marche ...


"Stephane TUET" a écrit dans le message de news:
Oj%23M22$
Merci pour ta réponse et tu as bien compris ce que j'ai essayé de faire
(et j'en suis content, au moins même si mon code ne marche pas, il a été
compris :-) ). frm_wait est bien défini en global puisqu'il peut être
appelé à divers endroit dans mon application (je compte le faire à chaque
appel d'un service web).

L'appel du service web lui est réalisé dans le thread principal qui se
trouve donc bloqué.

J'ai également essayé de déplacé le lancement du timer comme ceci :

Public Sub DebutAttente()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

TimerWait.Interval = K_TIMER_WAIT

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub


Mais j'ai l'impression de ne pouvoir lancer le thread qu'une seule fois,
au deuxième appel à DebutAttente, j'ai un plantage...

Merci de ton aide.

Steph


"AlexC" <(@Anti-Spam)#(@Anti-Spam)#> a écrit
dans le message de news: uupRlv$
d'après le code que tu donne :

Tu execute DebutAttente qui lance un timer...
Tu lances Ton service web qui traite sa tache ....
Quand il a finit sa tache tu execute FinAttente.

Tu as définit une intervalle pour le timer ( c'est un exemple ) 10ms
Donc au bout de 10ms le timer va s'arreter et lancer un autre Thread (
indépendant du service Web )
Ce Thread affiche la fenetre et s'arretes ( je suppose que frm_wait est
globale )

Ma question est :

Le lancement du service web se fait - il via un autre thread ? ou bloque
t- il le thread principal ?
si il se fait via un thread à part, il est normal que la fenetre se
referme.

"Stephane TUET" a écrit dans le message de news:
OgJHmX$
Bonjour

J'essaie depuis un bon moment maintenant et sans succés de réaliser
un message d'attente pendant un traitement (en fait, un appel à un Web
Service en mode synchrone). Le but est que le message apparaisse lorsque
le temps d'attente devient trop long... Comme j'ai également une image
Gif animée sur cette form, je suppose qu'il faut que je crée un nouveau
Thread pour que l'animation marche correctement et pour gérer
l'ouverture retardée.

J'ai bien commencé à écrire quelques lignes de code, mais ça ne
fonctionne par comme je veux (en général je n'ai rien du tout qui
s'affiche :-) )

Dans un module j'ai les déclarations suivantes :
Private frm_wait As New frm_wait 'la fenêtre d'attente

Private WithEvents TimerWait As New Timer

Private Thread As New Threading.Thread(AddressOf DebutThreadAttente)


Dans ma fenêtre où il y a l'appel au service web j'ai qq chose du style
:

DebutAttente()
try
'Appel du service web
catch
'gestion d'erreur
end try
FinAttente()


Et mes procédures sont les suivantes :

Public Sub DebutAttente()

TimerWait.Interval = K_TIMER_WAIT 'la variable définie en ms pour
le temps d'attente avant affichage de la fenêtre

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub



Avec cela je voulais réaliser uniquement un Show/Hide de la fenêtre
d'attente avant/après chacun des traitements mais ça ne marche pas...
J'avoue que je suis bien perdu avec ce thread. Si quelqu'un pouvait
m'indiquer une piste pour réaliser cela...

Merci d'avance

Steph











Avatar
Stephane TUET
Euh oui mais si je fais ça, je n'ai plus de Thread et donc finalement ça
revient à retarder l'appel de mon service web le temps du Timer, ou alors
y'a quelque chose que je ne comprends pas bien...


"AlexC" <(@Anti-Spam)#(@Anti-Spam)#> a écrit
dans le message de news: %
J'ai trouvé, mais je ne comprends pas pourquoi ...

Il suffit d'enlever le Thread "DebutThreadAttente"
et de remplacer dans le gestionnaire d'évènemement du timer le
Thread.start par
frm_wait.show et ca marche ...


"Stephane TUET" a écrit dans le message de news:
Oj%23M22$
Merci pour ta réponse et tu as bien compris ce que j'ai essayé de faire
(et j'en suis content, au moins même si mon code ne marche pas, il a été
compris :-) ). frm_wait est bien défini en global puisqu'il peut être
appelé à divers endroit dans mon application (je compte le faire à chaque
appel d'un service web).

L'appel du service web lui est réalisé dans le thread principal qui se
trouve donc bloqué.

J'ai également essayé de déplacé le lancement du timer comme ceci :

Public Sub DebutAttente()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

TimerWait.Interval = K_TIMER_WAIT

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub


Mais j'ai l'impression de ne pouvoir lancer le thread qu'une seule fois,
au deuxième appel à DebutAttente, j'ai un plantage...

Merci de ton aide.

Steph


"AlexC" <(@Anti-Spam)#(@Anti-Spam)#> a écrit
dans le message de news: uupRlv$
d'après le code que tu donne :

Tu execute DebutAttente qui lance un timer...
Tu lances Ton service web qui traite sa tache ....
Quand il a finit sa tache tu execute FinAttente.

Tu as définit une intervalle pour le timer ( c'est un exemple ) 10ms
Donc au bout de 10ms le timer va s'arreter et lancer un autre Thread (
indépendant du service Web )
Ce Thread affiche la fenetre et s'arretes ( je suppose que frm_wait est
globale )

Ma question est :

Le lancement du service web se fait - il via un autre thread ? ou bloque
t- il le thread principal ?
si il se fait via un thread à part, il est normal que la fenetre se
referme.

"Stephane TUET" a écrit dans le message de news:
OgJHmX$
Bonjour

J'essaie depuis un bon moment maintenant et sans succés de réaliser
un message d'attente pendant un traitement (en fait, un appel à un Web
Service en mode synchrone). Le but est que le message apparaisse
lorsque le temps d'attente devient trop long... Comme j'ai également
une image Gif animée sur cette form, je suppose qu'il faut que je crée
un nouveau Thread pour que l'animation marche correctement et pour
gérer l'ouverture retardée.

J'ai bien commencé à écrire quelques lignes de code, mais ça ne
fonctionne par comme je veux (en général je n'ai rien du tout qui
s'affiche :-) )

Dans un module j'ai les déclarations suivantes :
Private frm_wait As New frm_wait 'la fenêtre d'attente

Private WithEvents TimerWait As New Timer

Private Thread As New Threading.Thread(AddressOf DebutThreadAttente)


Dans ma fenêtre où il y a l'appel au service web j'ai qq chose du style
:

DebutAttente()
try
'Appel du service web
catch
'gestion d'erreur
end try
FinAttente()


Et mes procédures sont les suivantes :

Public Sub DebutAttente()

TimerWait.Interval = K_TIMER_WAIT 'la variable définie en ms pour
le temps d'attente avant affichage de la fenêtre

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub



Avec cela je voulais réaliser uniquement un Show/Hide de la fenêtre
d'attente avant/après chacun des traitements mais ça ne marche pas...
J'avoue que je suis bien perdu avec ce thread. Si quelqu'un pouvait
m'indiquer une piste pour réaliser cela...

Merci d'avance

Steph















Avatar
Stephane TUET
Ah ou alors, c'est parce que le gestionnaire d'évènement du timer est
lui-même un thread à part... Mystère !


"AlexC" <(@Anti-Spam)#(@Anti-Spam)#> a écrit
dans le message de news: %
J'ai trouvé, mais je ne comprends pas pourquoi ...

Il suffit d'enlever le Thread "DebutThreadAttente"
et de remplacer dans le gestionnaire d'évènemement du timer le
Thread.start par
frm_wait.show et ca marche ...


"Stephane TUET" a écrit dans le message de news:
Oj%23M22$
Merci pour ta réponse et tu as bien compris ce que j'ai essayé de faire
(et j'en suis content, au moins même si mon code ne marche pas, il a été
compris :-) ). frm_wait est bien défini en global puisqu'il peut être
appelé à divers endroit dans mon application (je compte le faire à chaque
appel d'un service web).

L'appel du service web lui est réalisé dans le thread principal qui se
trouve donc bloqué.

J'ai également essayé de déplacé le lancement du timer comme ceci :

Public Sub DebutAttente()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

TimerWait.Interval = K_TIMER_WAIT

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub


Mais j'ai l'impression de ne pouvoir lancer le thread qu'une seule fois,
au deuxième appel à DebutAttente, j'ai un plantage...

Merci de ton aide.

Steph


"AlexC" <(@Anti-Spam)#(@Anti-Spam)#> a écrit
dans le message de news: uupRlv$
d'après le code que tu donne :

Tu execute DebutAttente qui lance un timer...
Tu lances Ton service web qui traite sa tache ....
Quand il a finit sa tache tu execute FinAttente.

Tu as définit une intervalle pour le timer ( c'est un exemple ) 10ms
Donc au bout de 10ms le timer va s'arreter et lancer un autre Thread (
indépendant du service Web )
Ce Thread affiche la fenetre et s'arretes ( je suppose que frm_wait est
globale )

Ma question est :

Le lancement du service web se fait - il via un autre thread ? ou bloque
t- il le thread principal ?
si il se fait via un thread à part, il est normal que la fenetre se
referme.

"Stephane TUET" a écrit dans le message de news:
OgJHmX$
Bonjour

J'essaie depuis un bon moment maintenant et sans succés de réaliser
un message d'attente pendant un traitement (en fait, un appel à un Web
Service en mode synchrone). Le but est que le message apparaisse
lorsque le temps d'attente devient trop long... Comme j'ai également
une image Gif animée sur cette form, je suppose qu'il faut que je crée
un nouveau Thread pour que l'animation marche correctement et pour
gérer l'ouverture retardée.

J'ai bien commencé à écrire quelques lignes de code, mais ça ne
fonctionne par comme je veux (en général je n'ai rien du tout qui
s'affiche :-) )

Dans un module j'ai les déclarations suivantes :
Private frm_wait As New frm_wait 'la fenêtre d'attente

Private WithEvents TimerWait As New Timer

Private Thread As New Threading.Thread(AddressOf DebutThreadAttente)


Dans ma fenêtre où il y a l'appel au service web j'ai qq chose du style
:

DebutAttente()
try
'Appel du service web
catch
'gestion d'erreur
end try
FinAttente()


Et mes procédures sont les suivantes :

Public Sub DebutAttente()

TimerWait.Interval = K_TIMER_WAIT 'la variable définie en ms pour
le temps d'attente avant affichage de la fenêtre

TimerWait.Start()

End Sub



Private Sub TimerWait_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles TimerWait.Tick

TimerWait.Stop()

Thread.Start()

End Sub



Private Sub DebutThreadAttente()

frm_wait.Show()

End Sub



Public Sub FinAttente()

TimerWait.Stop()

frm_wait.Hide()

End Sub



Avec cela je voulais réaliser uniquement un Show/Hide de la fenêtre
d'attente avant/après chacun des traitements mais ça ne marche pas...
J'avoue que je suis bien perdu avec ce thread. Si quelqu'un pouvait
m'indiquer une piste pour réaliser cela...

Merci d'avance

Steph















Avatar
Elp
Salut,

On Thu, 6 Jan 2005 16:09:01 +0100, AlexC wrote:

J'ai trouvé, mais je ne comprends pas pourquoi ...

Il suffit d'enlever le Thread "DebutThreadAttente"
et de remplacer dans le gestionnaire d'évènemement du timer le Thread.start
par
frm_wait.show et ca marche ...



Dans ta methode précédente, tu lancait un thread qui se contentait
d'afficher ta fenetre d'attente de maniere non modale (Show ne bloque pas).
Donc ton thread affichait ta fenetre puis terminait (vu qu'il n'avait plus
rien a faire) entrainant du coup la destruction de ta fenetre. La solution
aurait été d'appeler ShowDialog (bloquante tant que la fenetre n'a pas été
fermée) au lieu de Show. Mais de toute facon, cette solution d'utilier un
autre thread pour afficher ta fenetre était tres crade et t'aurai apporté
tout un tas de bugs bizarres.

Dans ta nouvelle methode, j'imagine que utilise le timer de l'espace de nom
Windows.Form. Lorsque que ce timer "tick", ta fonction TimerWait_Tick est
executée dans le thread principal (d'ou le timer a été lancé) et non pas
dans un nouveau thread (c'est la particularité du timer Windows.From
comparé aux autres timers disponibles en .NET). Ce thread principal a 2
particularités:
- il ne termine que lorsque tu fermes ton appli
- il possede un boucle de message (c'est cette boucle qui permet aux
fenetres de rester affichées et de recevoir les evenements - ou messages -
clavier, souris...)

Donc ta fonction TimerWait_Tick affiche ta fenetre d'attente dans le thread
principal puis se termine. Seulement le thread dans lequel est affichée ta
fenetre est toujours la lui, ta fenetre n'est donc pas détruite et reste
affichée.

Cela dit, cela m'étonne quand meme que ta fenetre soit affichée. Car
lorsque TimerWait_Tick s'exécute, ton thread principal devrait en théorie
etre bloqué par l'appel synchrone au service Web et donc incapable de faire
quoique ce soit, y compris d'afficher ta fenetre (qui ne serait du coup
affichée qu'a la fin de l'appel au service web). Donc je pense que lors de
tes tests, le timer a tické avant que l'appel au web service n'ai
réellement commencé ou alors lorsqu'il était déja terminé. Ce qui n'est pas
ce que tu cherche a faire je pense.

Dans tout les cas, ton approche ne me semble pas etre la bonne. La regle
d'or pour les applis Windows (c'est dans la doc): tout ce qui a trait a
l'UI doit se faire dans un et un seul thread (le thread principal). Sinon,
bugs bizarres quasiment certains (d'ou mon commentaire sur ta premiere
solution). De plus, toute opération longue et bloquante doit etre évitée
dans le thread principal (celui de l'UI) afin d'éviter que ton appli ne
soit gelée. Donc la solution est: lance l'appel a ton web service de
maniere asychrone en passant l'adresse d'une fonction callback a appeler
lorsque l'appel sera terminé; puis démarre ton Timer; puis dans ta fonction
callback ferme la fenetre d'attente si elle a été affichée.
Avatar
Stephane TUET
"Elp" a écrit dans le message de news:
171lkqy2fi1uk$.1vuf1v9c5943b$
Salut,

On Thu, 6 Jan 2005 16:09:01 +0100, AlexC wrote:

J'ai trouvé, mais je ne comprends pas pourquoi ...

Il suffit d'enlever le Thread "DebutThreadAttente"
et de remplacer dans le gestionnaire d'évènemement du timer le
Thread.start
par
frm_wait.show et ca marche ...



Dans ta methode précédente, tu lancait un thread qui se contentait
d'afficher ta fenetre d'attente de maniere non modale (Show ne bloque
pas).
Donc ton thread affichait ta fenetre puis terminait (vu qu'il n'avait plus
rien a faire) entrainant du coup la destruction de ta fenetre. La solution
aurait été d'appeler ShowDialog (bloquante tant que la fenetre n'a pas été
fermée) au lieu de Show. Mais de toute facon, cette solution d'utilier un
autre thread pour afficher ta fenetre était tres crade et t'aurai apporté
tout un tas de bugs bizarres.



Ok, je comprends pour la destruction de la fenêtre, maintenant ça me parait
logique. Par contre, qu'est ce que tu entends par bugs bizarres ? Des bugs
d'affichage je suppose ?


Dans ta nouvelle methode, j'imagine que utilise le timer de l'espace de
nom
Windows.Form. Lorsque que ce timer "tick", ta fonction TimerWait_Tick est
executée dans le thread principal (d'ou le timer a été lancé) et non pas
dans un nouveau thread (c'est la particularité du timer Windows.From
comparé aux autres timers disponibles en .NET). Ce thread principal a 2
particularités:
- il ne termine que lorsque tu fermes ton appli
- il possede un boucle de message (c'est cette boucle qui permet aux
fenetres de rester affichées et de recevoir les evenements - ou messages -
clavier, souris...)

Donc ta fonction TimerWait_Tick affiche ta fenetre d'attente dans le
thread
principal puis se termine. Seulement le thread dans lequel est affichée ta
fenetre est toujours la lui, ta fenetre n'est donc pas détruite et reste
affichée.



Donc je suppose que si je m'amuse à mettre un ShowDialog dans le
TimeWait_Tick, mon appli se retrouve bloquée sur la fenêtre d'attente tant
qu'elle n'est pas fermée ?

Cela dit, cela m'étonne quand meme que ta fenetre soit affichée. Car
lorsque TimerWait_Tick s'exécute, ton thread principal devrait en théorie
etre bloqué par l'appel synchrone au service Web et donc incapable de
faire
quoique ce soit, y compris d'afficher ta fenetre (qui ne serait du coup
affichée qu'a la fin de l'appel au service web). Donc je pense que lors de
tes tests, le timer a tické avant que l'appel au web service n'ai
réellement commencé ou alors lorsqu'il était déja terminé. Ce qui n'est
pas
ce que tu cherche a faire je pense.



C'est en effet ce qui se passe, rien de s'affiche, là aussi maintenant je
comprends pourquoi :-) (décidemment...)

Dans tout les cas, ton approche ne me semble pas etre la bonne. La regle
d'or pour les applis Windows (c'est dans la doc): tout ce qui a trait a
l'UI doit se faire dans un et un seul thread (le thread principal). Sinon,
bugs bizarres quasiment certains (d'ou mon commentaire sur ta premiere
solution). De plus, toute opération longue et bloquante doit etre évitée
dans le thread principal (celui de l'UI) afin d'éviter que ton appli ne
soit gelée. Donc la solution est: lance l'appel a ton web service de
maniere asychrone en passant l'adresse d'une fonction callback a appeler
lorsque l'appel sera terminé; puis démarre ton Timer; puis dans ta
fonction
callback ferme la fenetre d'attente si elle a été affichée.



Ok, c'est vrai que c'est beaucoup plus élégant comme méthode... Par contre,
c'était justement parce que l'appli se retrouve "gelée" que je voulais
afficher ce message d'attente... En mode asynchrone, je suppose que
l'utilisateur pourrait faire tout et n'importe quoi pendant l'appel au
service web, ce qui peut parfois être embétant... Imaginons par exemple que
l'utilisateur soit en train de créer un fournisseur, l'enregistrement de
celui-ci se fait via un service web, et en mode asynchrone, l'utilisateur se
retrouve à pouvoir faire des modifs alors que l'enregistrement est en cours,
c'est pas top je trouve (mais y'a sûrement un autre moyen d'éviter cela...).
En fait ma question reviendrait plutôt à quelque chose du genre : tout les
appels à des services web ne peuvent pas forcément se faire en mode
asynchrone, et donc comment faire dans ce cas là ? (si je dis n'importe quoi
je m'en excuse d'avance :-) )

En tout cas merci beaucoup pour ton aide et tes explications.

Steph
Avatar
Christophe Lauer [MS]
Bonjour,

Stephane TUET wrote:

Ok, c'est vrai que c'est beaucoup plus élégant comme méthode... Par
contre, c'était justement parce que l'appli se retrouve "gelée" que
je voulais afficher ce message d'attente...



En fait , le c'est le thread principal de l'application qui a gére
l'affichage et qui doit attendre le retour du service web et donc "gèle"
l'application.

En mode asynchrone, je
suppose que l'utilisateur pourrait faire tout et n'importe quoi
pendant l'appel au service web, ce qui peut parfois être embétant...
Imaginons par exemple que l'utilisateur soit en train de créer un
fournisseur, l'enregistrement de celui-ci se fait via un service web,
et en mode asynchrone, l'utilisateur se retrouve à pouvoir faire des
modifs alors que l'enregistrement est en cours, c'est pas top je
trouve



Les bases de données gère tout ça très bien. Il faut simplement gérer
correctement les exceptions qu'elles peuvent remonter dans ces cas.

Si on reprend votre exemple avec non pas un mais deux utilisateurs, votre
solution ne protège en rien le fait qu'un utilisateur peut agir sur le même
enregistrement qu'un autre utilisateur. L'intérêt est donc assez limité.

(mais y'a sûrement un autre moyen d'éviter cela...). En fait
ma question reviendrait plutôt à quelque chose du genre : tout les
appels à des services web ne peuvent pas forcément se faire en mode
asynchrone, et donc comment faire dans ce cas là ? (si je dis
n'importe quoi je m'en excuse d'avance :-) )




Hmmm, pas certain de bien comprendre la question. Pour les besoins
spécifiques tels que les appels dans des contextes transactionnels, il fut
en passer par les extensions proposées dans le WSE Toolkit.

HTH,

--
Christophe Lauer - Relations Techniques Editeurs de Logiciels
Division Développeurs et Plateforme d'Entreprise - Microsoft France
http://www.microsoft.com/france/msdn/
This posting is provided "AS IS" with no warranties, and confers no
rights.
Avatar
Elp
On Thu, 6 Jan 2005 18:02:53 +0100, Stephane TUET wrote:

Ok, je comprends pour la destruction de la fenêtre, maintenant ça me parait
logique. Par contre, qu'est ce que tu entends par bugs bizarres ? Des bugs
d'affichage je suppose ?



Oui et autres aussi. Regarde dans la doc sur MSDN (sans doute dans la doc
de Form ou de Control), il est clairement dit que tout appel de fonctions
sur un Control/Form ou access a l'une de ses propriétés doit etre fait
depuis le thread ou se trouve ce Control/Form. Il y a quelques exceptions a
la regle comme la methode Invoke par exemple qui te permet justement de
pouvoir appeler une fonction d'un Control depuis un autre thread.


Donc je suppose que si je m'amuse à mettre un ShowDialog dans le
TimeWait_Tick, mon appli se retrouve bloquée sur la fenêtre d'attente tant
qu'elle n'est pas fermée ?



Oui.

Ok, c'est vrai que c'est beaucoup plus élégant comme méthode... Par contre,
c'était justement parce que l'appli se retrouve "gelée" que je voulais
afficher ce message d'attente... En mode asynchrone, je suppose que
l'utilisateur pourrait faire tout et n'importe quoi pendant l'appel au
service web, ce qui peut parfois être embétant...



C'est un probleme courant. Tu peux trouver plusieurs solutions, par
exemple:
- mettre la propriété Enabled de ta form a false. Cela revient a geler
artificiellement ta form
- griser les champs/controles qui ne peuvent pas etre utilisés pendant
l'appel au service Web (en utilisant la propriété Enabled de ces Controls).
Cela revient un peu a la meme solution qu'au dessus mais en moins
perturbant pour l'utilisateur qui généralement n'apprécie guere lorsqu'une
fenetre est totalement gelée
- Afficher ta fenetre d'attente de maniere modale (avec ShowDialog) et
passer en parametrer a ShowDialog ta fenetre principale. De cette maniere,
l'utilisateur ne pourra pas cliquer sur la fenetre principale tant que la
fenetre d'attente sera affichée.

En fait ma question reviendrait plutôt à quelque chose du genre : tout les
appels à des services web ne peuvent pas forcément se faire en mode
asynchrone, et donc comment faire dans ce cas là ? (si je dis n'importe quoi
je m'en excuse d'avance :-) )



En fait, je ne vois pas trop pourquoi un appel a un service Web ne pourrai
pas se faire de maniere asynchrone. Mais si tu y tiens vraiment, alors
lance un timer, affiche ta fenetre d'attente avec ShowDialog, puis dans
l'évenement du Timer, vérifie d'abord que ta fenetre est affichée puis
appel ton service Web. Mais que je vois vraiment pas l'interet la.
1 2