J'ai une classe qui appelle une interface SOAP et obtient un tableau de données. Toutefois, si cette demande est terminée, cela jette une exception. C'est bon. Cependant, je veux que mon programme tente de rendre cet appel à nouveau. Si cela tente, j'aimerais que cela continue à faire cet appel jusqu'à ce qu'il réussisse. Comment puis-je accomplir cela?
Par exemple: P>
try { salesOrdersArray = MagServ.salesOrderList(sessID, filter); } catch { ?? What Goes Here to FORCE the above line of code to rerun until it succeeds. }
11 Réponses :
Si vous ne pouvez pas changer le délai d'attente, il faut fonctionner ci-dessous. salutordersarray doit être initialisé à null code>.
while(salesOrdersArray == null)
{
try
{
salesOrdersArray = MagServ.salesOrderList(sessID, filter);
}
catch
{
// Log failure
}
}
+1: J'aime ça un peu mieux que la réponse de Jon. Je pense que cela rend la condition finale de la boucle plus évidente.
Ce n'est généralement pas une bonne idée d'utiliser des exceptions comme flux de contrôle, mais cela fera ce que vous avez demandé.
bool repeat = true; while (repeat) { try { salesOrdersArray = MagServ.salesOrderList(sessID, filter); repeat = false; } catch { } }
Vous avez juste besoin de boucle pour toujours: Notez que vous devriez presque certainement pas em> réellement en boucle pour toujours. Vous devriez certainement certainement avoir un nombre maximum de tentatives et probablement seulement attraper des exceptions em> spécifiques. Attraper tous em> exceptions pour toujours em> pourrait être épouvantable ... imaginez si saléServette code> (nom de la méthode non conventionnelle, BTW) lance
argumentnullexception code> Parce que vous avez un bogue et
filtre code> est null ... Est-ce que vous vraiment em> veux attacher 100% de votre CPU pour toujours? P> P>
Cela ne pouvait-il pas (potentiellement) attacher des ressources système et / ou rendre l'application appelante ne répondant-t-elle? Ne sonne pas comme la meilleure solution pour moi ...
@Tim: J'ajoutais le paragraphe ci-dessous - fondamentalement, le code répond directement à la question, mais le paragraphe explique que ce n'est probablement pas une bonne idée :)
+1 Pour des exceptions spécifiques, je tapais mon commentaire sur la question pendant votre édition.
Je sais que je sais que des exceptions spécifiques, des erreurs de savon, etc. Vous avez oublié les joies de la pause, merci.
@PSYKLOPZ: Vous spécifiez le type d'exception dans le bloc Catch: Catch (SoapException) Code> etc. Vous pouvez spécifier plusieurs types d'exception différents dans plusieurs blocs de capture.
Lorsque je fais ce genre de chose, j'ai mis dans un dormir code> de la durée appropriée de sorte qu'il n'utilise pas 100% de la CPU en attente de service de service pour revenir en ligne. Je pourrais même inclure une brachette exponentielle limitée (comme TCP) afin qu'elle récupère rapidement des problèmes de réseau mineurs mais essaie une fois toutes les quelques minutes si le service est en panne pendant une période prolongée.
Vous pouvez également obtenir l'heure actuelle avant, puis attendez que le diff b / w puis et maintenant est> 5 sec, puis rompez (ou bien que vous voulez)
ESSAYEZ
bool failed = false; do { try { salesOrdersArray = MagServ.salesOrderList(sessID, filter); } catch { failed = true; } } while(failed);
Essayez quelque chose comme ceci:
var failed = true; while (failed) { try { salesOrdersArray = MagServ.salesOrderList(sessID, filter); failed = false; } catch { } }
Bien que je ne vous recommandais pas de le faire pour un nombre infini de fois, vous pouvez faire une fonction distincte de cette phrase:
void GoConnect() { try { salesOrdersArray = MagServ.salesOrderList(sessID, filter); } catch { GoConnect(); } }
while(salesOrdersArray == null){ try { salesOrdersArray = MagServ.salesOrderList(sessID, filter); } catch(salesOrderException e) { log(e.message); } } This will run forever, and is using exceptions as a loop which is slow. Is there a way you can modify your function that it returns null, instead of throwing an exception? If you're expecting that this call will fail regularly, don't use a try/catch block.
Je suis ce modèle afin de résoudre ce problème:
public void Send(String data, Int32 attemptNumber) { try { yourCodeHere(data); } catch (WebException ex) { if (attemptNumber > 0) Send(data, --attemptNumber); else throw new AttemptNumberExceededException("Attempt number exceeded!", ex); } catch (Exception ex) { //Log pourpose code goes here! throw; } }
Pourquoi ne devrait-je pas? Mon point est le même que Jon Skeet, au-dessous du code qu'il a écrit
Ne jette ex; code> Stackoverflow.com/questions/178456/... Stackoverflow.com/questions/22623/...
Merci @asawyer ne savait pas à ce sujet, alors j'ai édité ma réponse! Est-ce que ça va maintenant?
Deux choses: 1- Vous ne voulez presque jamais attraper la classe d'exception de base, et si vous le faites, c'est à peu près seulement à des fins de journalisation, puis lancer code> à nouveau. 2 - Ne jetez jamais la base
exception code> classe. Vous forcez de consommer du code dans la mauvaise pratique de la capture d'exception code> code>. Utilisez une sous-classe plus appropriée ou créez le vôtre.
Ça fait un vrai sens ...! Vous n'avez jamais pensé de cette façon ... Désolé de vous ennuyer, qu'en est-il de maintenant?
Il suffit de prendre un peu de temps pour lire les meilleures pratiques et vous serez en affaires en un rien de temps. Heres Quelques bons liens: blogs.msdn. COM / B / ERICLIPPERT / Archive / 2008/09/10 / ... CodeProject .com / kb / architecture / excepteBestpractices.aspx
Vous devez placer le bloc Essayer / Catch à l'intérieur d'une construction de boucle. Si vous souhaitez ne pas consommer à 100% de votre processeur, placez un thread.sleep dans le bloc de capture, chaque fois que chaque fois une exception survient, elle attendra du temps, libérant le processeur pour faire d'autres choses.
// iterate 100 times... not forever! for (int i = 0; i < 100; i++) { try { // do your work here; break; // break the loop if everything is fine } catch (TimeOutException) { Thread.Sleep(1000); } }
J'utiliserai une queue forte> transactionnelle forte> (MSMQ) pour stocker l'appel de service. Une boucle va ressentir des messages et appelera le service dans un transaction de transaction, si l'appel échoue, le message semble être toujours dans la file d'attente. Un délai d'attente OV Erall peut être spécifié en ajoutant un temps à expirer dans le message. Cette solution est bonne si vous voulez vraiment une solution fiable puisque j'ai deviné que l'appelant que l'opération est critique. P>
Augmenter le délai d'attente afin que cela ne jette pas l'exception?
Vous pouvez simplement appeler la méthode à nouveau à partir du bloc de capture, mais i> - que se passe-t-il si le service est en panne pendant une période prolongée? Voulez-vous que la méthode fonctionne de manière récursive pendant 24 heures? Je recommanderais de le limiter à un nombre défini de tentatives.
Sur toutes ces réponses, une personne ne vous dit pas d'attraper une exception plus précise. Et si votre bloc d'essai contient des objets dans un état non valide pour obtenir le
salopeOrderList code>? Réessayer ne réussira jamais.