83 votes

Attendent dans le bloc catch

J'ai le code suivant:

WebClient wc = new WebClient();
string result;
try
{
  result = await wc.DownloadStringTaskAsync( new Uri( "http://badurl" ) );
}
catch
{
  result = await wc.DownloadStringTaskAsync( new Uri( "http://fallbackurl" ) );
}

Fondamentalement, je veux le télécharger à partir d'une URL et quand il échoue, avec une exception je veux télécharger à partir d'un autre URL. Les deux temps async bien sûr. Cependant, le code ne compile pas, en raison de

erreur CS1985: Ne pas attendre, dans le corps d'une clause catch

OK, il est interdit, pour quelque raison que ce soit, mais quel est le bon modèle de code ici?

EDIT:

La bonne nouvelle est que C# 6.0 permettra vraisemblablement attendre des appels à la fois dans les captures et enfin les blocs.

101voto

svick Points 81772

Vous pouvez réécrire ce code pour déplacer l' await de la catch bloc à l'aide d'un drapeau:

WebClient wc = new WebClient();
string result = null;
bool downloadSucceeded;
try
{
  result = await wc.DownloadStringTaskAsync( new Uri( "http://badurl" ) );
  downloadSucceeded = true;
}
catch
{
  downloadSucceeded = false;
}

if (!downloadSucceeded)
  result = await wc.DownloadStringTaskAsync( new Uri( "http://fallbackurl" ) );

24voto

Craig Points 2715

En attente dans un bloc catch, il est maintenant possible de l'Utilisateur Final Aperçu de Roslyn comme indiqué ici (sous vous Attendent dans catch/finally)

L'exemple ci est

try … catch { await … } finally { await … }

9voto

Darragh Points 141

Cela semble fonctionner.

        WebClient wc = new WebClient();
        string result;
        Task<string> downloadTask = wc.DownloadStringTaskAsync(new Uri("http://badurl"));
        downloadTask = downloadTask.ContinueWith(
            t => {
                return wc.DownloadStringTaskAsync(new Uri("http://google.com/")).Result;
            }, TaskContinuationOptions.OnlyOnFaulted);
        result = await downloadTask;

-1voto

Vlad Bezden Points 5024

Vous pouvez envelopper votre appel dans une autre Tâche et appel ContinueWith. Ainsi, lorsque la tâche ne parvient pas à appeler la mauvaise url, ce qui fera appel à continuer avec laquelle vous pouvez spécifier les secours url.

public async Task<string> GetUrlData()
{
    var wc = new WebClient();

    var result = await Task.Factory.StartNew(() =>
    {
        return wc.DownloadStringTaskAsync(new Uri("http://www.google.com")).Result;
    }).ContinueWith(antecedent =>
    {
        // check if there was an error in ancendent task and if there was an error then clear it,
        // and call fallback url
        // otherwise return result from antecedent task
        if (antecendent.Status == TaskStatus.Faulted)
        {       
            antecendent.Exception.Handle(error => {return true;});
            return wc.DownloadStringTaskAsync(new Uri("http://msdn.com")).Result;
        }
        else
            return antecedent.Result;
    });

    return result;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X