Meilleure façon d’écrire la logique de nouvelle tentative sans goto

Existe-t-il un meilleur moyen d’écrire ce code sans utiliser goto ? Cela semble maladroit, mais je ne peux pas penser à un meilleur moyen. Je dois pouvoir effectuer une nouvelle tentative, mais je ne veux dupliquer aucun code.

 public void Write(ssortingng body) { bool retry = false; RetryPoint: try { m_Outputfile.Write(body); m_Outputfile.Flush(); } catch (Exception) { if( retry ) throw; // try to re-open the file... m_Outputfile = new StreamWriter(m_Filepath, true); retry = true; goto RetryPoint; } } 

Voici la logique de base que j’utiliserais à la place d’une instruction goto:

 bool succeeded = false; int sortinges = 2; do { try { m_Outputfile = new StreamWriter(m_Filepath, true); m_Outputfile.Write(body); m_Outputfile.Flush(); succeeded = true; } catch(Exception) { sortinges--; } } while (!succeeded && sortinges > 0); 

J’ai juste ajouté la logique du nombre d’essais, même si la question initiale n’en avait pas.

La solution de Michael ne répond pas tout à fait aux exigences, qui consistent à réessayer un nombre de fois déterminé, en lançant le dernier échec.

Pour cela, je recommanderais une simple boucle pour décompter. Si vous réussissez, quittez avec pause (ou, le cas échéant, revenez). Sinon, laissez le contrôle vérifier si l’index est réduit à 0. Si tel est le cas, redissortingbuez au lieu de vous connecter ou de ne pas tenir compte.

 public void Write(ssortingng body, bool retryOnError) { for (int sortinges = MaxResortinges; sortinges >= 0; sortinges--) { try { _outputfile.Write(body); _outputfile.Flush(); break; } catch (Exception) { if (sortinges == 0) throw; _outputfile.Close(); _outputfile = new StreamWriter(_filepath, true); } } } 

Dans l’exemple ci-dessus, un retour aurait été bien, mais je voulais montrer le cas général.

La réponse de @ Michael (avec un bloc de capture correctement mis en œuvre) est probablement la plus facile à utiliser dans votre cas, et la plus simple. Toutefois, dans l’intérêt de présenter des alternatives, voici une version qui intègre le contrôle de stream “nouvelle tentative” dans une méthode distincte:

 // define a flow control method that performs an action, with an optional retry public static void WithRetry( Action action, Action recovery ) { try { action(); } catch (Exception) { recovery(); action(); } } public void Send(ssortingng body) { WithRetry(() => // action logic: { m_Outputfile.Write(body); m_Outputfile.Flush(); }, // retry logic: () => { m_Outputfile = new StreamWriter(m_Filepath, true); }); } 

Vous pouvez, bien entendu, améliorer cela avec des éléments tels que le nombre de tentatives, une meilleure propagation des erreurs, etc.

Et si vous le mettez en boucle? Quelque chose de semblable à cela, peut-être.

 while(tryToOpenFile) { try { //some code } catch { } finally { //set tryToOpenFile to false when you need to break } } 
 public void Write(ssortingng body, bool retryOnError) { try { m_Outputfile.Write(body); m_Outputfile.Flush(); } catch (Exception) { if(!retryOnError) throw; // try to re-open the file... m_Outputfile = new StreamWriter(m_Filepath, true); Write(body, false); } } 

Essayez quelque chose comme ce qui suit:

 int tryCount = 0; bool succeeded = false; while(!succeeded && tryCount<2){ tryCount++; try{ //interesting stuff here that may fail. succeeded=true; } catch { } } 

avec un booléen

 public void Write(ssortingng body) { bool NotFailedOnce = true; while (true) { try { _outputfile.Write(body); _outputfile.Flush(); return; } catch (Exception) { NotFailedOnce = !NotFailedOnce; if (NotFailedOnce) { throw; } else { m_Outputfile = new StreamWriter(m_Filepath, true); } } } }