OVH Cloud OVH Cloud

blocage d'application lors d'un appel asynchone à un WebService

5 réponses
Avatar
Charly28
Bonjour,

Nous avons développé une application Winform avec DotNet 2005 en c#.
Lors d'appels asynchrones à des méthodes WebService, l'application se bloque
complètement sur certains postes de nos clients (windows XP Pro SP2) et il
faut la terminer à partir du gestionnaire de tâches. Les appels synchrones
quant à eux fonctionnent sans problème.
Par ailleurs, avec un analyseur de flux, nous avons pu constater que les
échanges avec le serveur sont tout à fait conformes même dans le cas où
l'application cliente se bloque.

Quelqu'un a-t'il déja constaté ce problème et y aurait-il une solution autre
que transformer tous les appels en synchrone ?

Merci d'avance.

5 réponses

Avatar
Mehdi
On Tue, 21 Nov 2006 02:33:02 -0800, Charly28 wrote:

Nous avons développé une application Winform avec DotNet 2005 en c#.
Lors d'appels asynchrones à des méthodes WebService, l'application se bloque
complètement sur certains postes de nos clients (windows XP Pro SP2) et il
faut la terminer à partir du gestionnaire de tâches. Les appels synchrones
quant à eux fonctionnent sans problème.
Par ailleurs, avec un analyseur de flux, nous avons pu constater que les
échanges avec le serveur sont tout à fait conformes même dans le cas où
l'application cliente se bloque.

Quelqu'un a-t'il déja constaté ce problème et y aurait-il une solution autre
que transformer tous les appels en synchrone ?



Ce genre de probleme avec des appels asynchrones est la plupart du temps du
au fait que la méthode callback, appelée lorsque l'appel est terminé et
exécutée dans un thread du threadpool, tente d'accéder a des Controls
(buttons, fenetres, text box...) sans auparavant marshaller l'appel dans le
thread de l'UI.

Accéder a des controles de l'interface graphique sous Windows depuis un
autre thread que le thread de l'UI n'est pas supporté. Tenter de le faire
parfois semble fonctionner, parfois crash l'application d'une maniere
totalement imprévisible. Je commencerai par analyser le code afin de voir
s'il n'y aurai pas un bout de code quelque part qui accede a l'interface
graphique alors qu'il n'est pas exéctuté dans le thread de l'UI.

Si ce n'est pas la cause du probleme, alors il doit y avoir un deadlock
quelque part.
Avatar
Charly28
Merci pour cette réponse rapide,

Après vérification du code, il n'y a aucun accès à des controles dans la
méthode de callback.
Le problème viendrai plutôt de la configuration des postes où il y a
blocage, car sur les postes où ces appels fonctionnent, je n'ai jamais eu
aucun blocage.
La question serait donc : qu'est ce qui, dans la configuration d'un poste,
pourrait bloquer les appels asynchrones à un webservice ?

"Mehdi" a écrit :

On Tue, 21 Nov 2006 02:33:02 -0800, Charly28 wrote:

> Nous avons développé une application Winform avec DotNet 2005 en c#.
> Lors d'appels asynchrones à des méthodes WebService, l'application se bloque
> complètement sur certains postes de nos clients (windows XP Pro SP2) et il
> faut la terminer à partir du gestionnaire de tâches. Les appels synchrones
> quant à eux fonctionnent sans problème.
> Par ailleurs, avec un analyseur de flux, nous avons pu constater que les
> échanges avec le serveur sont tout à fait conformes même dans le cas où
> l'application cliente se bloque.
>
> Quelqu'un a-t'il déja constaté ce problème et y aurait-il une solution autre
> que transformer tous les appels en synchrone ?

Ce genre de probleme avec des appels asynchrones est la plupart du temps du
au fait que la méthode callback, appelée lorsque l'appel est terminé et
exécutée dans un thread du threadpool, tente d'accéder a des Controls
(buttons, fenetres, text box...) sans auparavant marshaller l'appel dans le
thread de l'UI.

Accéder a des controles de l'interface graphique sous Windows depuis un
autre thread que le thread de l'UI n'est pas supporté. Tenter de le faire
parfois semble fonctionner, parfois crash l'application d'une maniere
totalement imprévisible. Je commencerai par analyser le code afin de voir
s'il n'y aurai pas un bout de code quelque part qui accede a l'interface
graphique alors qu'il n'est pas exéctuté dans le thread de l'UI.

Si ce n'est pas la cause du probleme, alors il doit y avoir un deadlock
quelque part.



Avatar
Mehdi
On Tue, 21 Nov 2006 10:14:02 -0800, Charly28 wrote:

Après vérification du code, il n'y a aucun accès à des controles dans la
méthode de callback.



Sur et certain ? Les méthode callback ne leveraient pas un évenement qui en
leverait un autre qui finalement tenterai d'accéder a une fenetre ou une
listbox ?

Le problème viendrai plutôt de la configuration des postes où il y a
blocage, car sur les postes où ces appels fonctionnent, je n'ai jamais eu
aucun blocage.
La question serait donc : qu'est ce qui, dans la configuration d'un poste,
pourrait bloquer les appels asynchrones à un webservice ?



Aucune idée. Il faudrai idéalement pouvoir débugger l'appli sur le poste
fautif.

Si j'ai bien compris, sur certain postes, *tous* les appels synchrones et
asynchrones fonctionnent correctement tandis que sur d'autre seuls les
appels synchrones fonctionnent et *tous* les appels asynchrones plantent
l'appli. Si c'est le cas, cela ressemble quand meme beaucoup a un bug dans
ton programme qui ne se manifeste que sur des configs particulieres. Est-ce
que sur le poste fautif, l'appel plante réellement ou est-ce juste un
time-out ?

J'ai dévelopé et utilisé un certain nombre de web services (certes tres
simples) depuis les débuts de .NET et n'ai jamais rencontré de tel
problemes.

J'ai rencontré un seul probleme vraiment bizarre jusqu'ici:
- service web tournant sous IIS et .NET 1.0
- client sous la forme d'un service windows tournant sous .NET 1.0
également.
- tous les appels au web service synchrones
- tout marchait bien mais de temps en temps, un appel au web service se
terminait en time-out sans aucune raison. Apres ca, *tous* les appels au
web service se terminaient en time-out. La seule solution pour faire
repartir le bouzin était de redémarrer le service Windows. Apres cela tout
fonctionnait correctement pendant quelques minutes, heures, jours ou meme
semaines mais il finissait toujours au bout d'un moment par planter avec
ces time-out a répétition. Je n'ai jamais réussi a trouver la raison de ces
time-out. En analysant les trames réseau, je pouvais voir que l'appel se
faisait correctement, que la réponse était recue quasiment immédiatement
mais pour une mystérieuse raison, l'appel ne retournait pas bien que les
donnée aient été recues et finissait en time-out. C'était un prototype.
Apres ca, on est passé a .NET 1.1 et redéveloppé le serveur et je n'ai
jamais rencontré ce genre de problemes depuis.

Donc voila, ca ne t'aide pas des masses j'imagine mais je pencherai quand
meme vers un bug subtil dans ton programme. Car il me parait bizarre qu'un
appel *asynchrone* puisse faire planter une appli. Si jamais quelque chose
se passe mal pendant l'appel, il est possible que tu recoives une exception
dans ta méthode callback ou peut etre meme que la méthode callback ne soit
jamais appelée (ce serait un gros bug la). Mais que ca plante completement
l'appli, non, la je ne vois pas. Je reste persuadé que tu fais quelque
chose de pas tres catholique dans ton callback.
Avatar
Charly28
"Mehdi" a écrit :

On Tue, 21 Nov 2006 10:14:02 -0800, Charly28 wrote:

> Après vérification du code, il n'y a aucun accès à des controles dans la
> méthode de callback.

Sur et certain ? Les méthode callback ne leveraient pas un évenement qui en
leverait un autre qui finalement tenterai d'accéder a une fenetre ou une
listbox ?



A tout hasard, ci-dessous le code de la méthode callback :
void wsService_TestCompleted(object sender, TestCompletedEventArgs e)
{
try
{
xeMessageRetour = e.Result.Description;
}
catch
{
CodeErreur = "-002";
MessageErreur = Traduction.ServiceMessagerie_ErreurConnection;
}
((AsyncStatut)e.UserState).Termine = true;
}

xeMesssageRetour est un XmlElement déclaré au niveau de la classe.
CodeErreur et Message Erreur sont de type String déclaré également au niveau
de la classe.
AsyncStatut défini uniquement une propriété de type Booleen (Termine) et ne
déclenche aucun évènement. Cette propriété sert juste à autoriser la sortie
d'une boucle d'attente juste après l'appel asynchrone.

Donc autant que je puisse juger, il n'y a rien qui corresponde au cas de
figure que tu m'as décrit.

Ne pouvant résoudre le problème j'ai donc décidé de le contourner en
autorisant à, défaut de mieux, le choix entre appels synchrone et asynchrone
; tant pis pour le rafraichissement de l'interface utilisateur pendant les
appels WS.

En tous cas , un grand merci pour le temps que tu as consacré à mon
problème. Et puis j'aurais appris qu'il ne faut pas manipuler des objets de
l'UI dans une méthode callback. Ca m'évitera de perdre du temps une autre
fois.
Avatar
Paul Bacelar
Pouvez-vous utiliser des outils comme WinDbg+AutodumpPlus pour savoir
précisément où il y a blocage ?
--
Paul Bacelar
MVP VC++


"Charly28" wrote in message
news:


"Mehdi" a écrit :

On Tue, 21 Nov 2006 10:14:02 -0800, Charly28 wrote:

> Après vérification du code, il n'y a aucun accès à des controles dans
> la
> méthode de callback.

Sur et certain ? Les méthode callback ne leveraient pas un évenement qui
en
leverait un autre qui finalement tenterai d'accéder a une fenetre ou une
listbox ?



A tout hasard, ci-dessous le code de la méthode callback :
void wsService_TestCompleted(object sender, TestCompletedEventArgs
e)
{
try
{
xeMessageRetour = e.Result.Description;
}
catch
{
CodeErreur = "-002";
MessageErreur =
Traduction.ServiceMessagerie_ErreurConnection;
}
((AsyncStatut)e.UserState).Termine = true;
}

xeMesssageRetour est un XmlElement déclaré au niveau de la classe.
CodeErreur et Message Erreur sont de type String déclaré également au
niveau
de la classe.
AsyncStatut défini uniquement une propriété de type Booleen (Termine) et
ne
déclenche aucun évènement. Cette propriété sert juste à autoriser la
sortie
d'une boucle d'attente juste après l'appel asynchrone.

Donc autant que je puisse juger, il n'y a rien qui corresponde au cas de
figure que tu m'as décrit.

Ne pouvant résoudre le problème j'ai donc décidé de le contourner en
autorisant à, défaut de mieux, le choix entre appels synchrone et
asynchrone
; tant pis pour le rafraichissement de l'interface utilisateur pendant les
appels WS.

En tous cas , un grand merci pour le temps que tu as consacré à mon
problème. Et puis j'aurais appris qu'il ne faut pas manipuler des objets
de
l'UI dans une méthode callback. Ca m'évitera de perdre du temps une autre
fois.