Question

Pour une raison quelconque, il y a une pause après le programme ci-dessous commence. Je crois que WebClient().DownloadStringTaskAsync() est la cause.

class Program
{
    static void Main(string[] args)
    {
        AsyncReturnTask();

        for (int i = 0; i < 15; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(100);
        }
    }

    public static async void AsyncReturnTask()
    {
        var result = await DownloadAndReturnTaskStringAsync();
        Console.WriteLine(result);
    }

    private static async Task<string> DownloadAndReturnTaskStringAsync()
    {
        return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));
    }
}

Pour autant que je comprends mon programme devrait commencer à compter de 0 à 15 immédiatement. Ai-je fait quelque chose de mal?

J'ai eu le même problème avec l'échantillon de téléchargement Netflix original (que vous obtenez avec CTP ) - après avoir appuyé sur le bouton de recherche les premiers gels UI - et après un certain temps, il est sensible tout en loadning les films suivants. Et je crois qu'il n'a pas gelé au PDC 2010 dans la présentation de Anders Hejlsberg.

Une autre chose. Quand au lieu de

return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));

J'utilise ma propre méthode:

return await ReturnOrdinaryTask();

Ce qui est:

public static Task<string> ReturnOrdinaryTask()
{
    var t = Task.Factory.StartNew(() =>
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("------------- " + i.ToString());
            Thread.Sleep(100);
        }
        return "some text";
    });
    return t;
}

Il fonctionne comme il se doit. Je veux dire qu'il ne se charge pas quoi que ce soit, mais il commence immédiatement et ne bloque pas le thread principal, tout en faisant son travail.

Modifier

OK, ce que je crois juste est maintenant: la fonction WebClient.DownloadStringTaskAsync est vissé vers le haut. Il devrait fonctionner sans la période de blocage initiale, comme ceci:

    static void Main(string[] args)
    {
        WebClient cli = new WebClient();
        Task.Factory.StartNew(() =>
            {
                cli.DownloadStringCompleted += (sender, e) => Console.WriteLine(e.Result);
                cli.DownloadStringAsync(new Uri("http://www.weather.gov"));
            });

        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(100);
        }
    }
Était-ce utile?

La solution

Alors que votre programme ne bloque pendant un certain temps, il fait l'exécution de reprise dans la boucle, avant que le résultat est renvoyé par le serveur distant.

Rappelez-vous que la nouvelle API async est toujours mono-thread. Alors WebClient().DownloadStringTaskAsync() doit encore exécuter sur votre fil jusqu'à ce que la demande a été préparée et envoyée au serveur, avant de pouvoir await et retour d'exécution de rendement à votre flux de programme principal ().

Je pense que les résultats que vous voyez sont dus au fait qu'il faut un certain temps pour créer et envoyer la demande à partir de votre machine. Tout d'abord quand cela a terminé, la mise en œuvre de DownloadStringTaskAsync peut attendre réseau IO et le serveur distant complet, et peut retourner l'exécution pour vous.

D'autre part, votre méthode de RunOrdinaryTask initialise juste une tâche et lui donne une charge de travail et dit pour commencer. Ensuite, il retourne immédiatement. Voilà pourquoi vous ne voyez pas un retard lors de l'utilisation RunOrdinaryTask.

Voici quelques liens sur le sujet: blog Eric Lippert (l'un des concepteurs de langue ), ainsi que Jon blog post initial de Skeet à ce sujet. Eric a une série de 5 messages sur le style de passage de continuation, ce qui est vraiment ce que async et await est vraiment. Si vous voulez comprendre la nouvelle fonctionnalité en détail, vous pouvez lire les messages de Eric sur CPS et Async. Quoi qu'il en soit, les deux liens ci-dessus un bon travail sur l'explication d'un fait très important:

  • Asynchronous! = Parallèle

En d'autres termes, async et await ne tourne pas de nouvelles discussions pour vous. Ils vous permet de reprendre simplement l'exécution de votre flux normal, lorsque vous faites une opération de blocage -. Fois où votre CPU serait tout simplement vous asseoir et ne rien faire dans un programme synchrone, en attendant une opération externe complète à

Modifier

Juste pour être clair sur ce qui se passe: les jeux de DownloadStringTaskAsync jusqu'à une continuation, puis appelle WebClient.DownloadStringAsync, sur le même fil, et puis l'exécution des rendements à votre code. Par conséquent, le temps de blocage que vous voyez avant que la boucle commence à compter, est le temps qu'il faut DownloadStringAsync pour terminer. Votre programme avec async et await est très proche d'être l'équivalent du programme suivant, qui présente le même comportement que votre programme: Un bloc initial, puis le comptage commence, et quelque part au milieu, les finitions op async et imprime le contenu de l'URL demandée:

    static void Main(string[] args)
    {
        WebClient cli = new WebClient();
        cli.DownloadStringCompleted += (sender, e) => Console.WriteLine(e.Result);
        cli.DownloadStringAsync(new Uri("http://www.weather.gov")); // Blocks until request has been prepared

        for (int i = 0; i < 15; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(100);
        }
    }

Note: Je ne suis pas un expert sur ce sujet, donc je peux me tromper sur certains points. Ne hésitez pas à corriger ma compréhension du sujet, si vous pensez que cela est faux. - Je viens de regarder la présentation PDC et a joué avec le CTP hier soir

Autres conseils

Êtes-vous sûr que la question n'est pas lié aux paramètres de configuration proxy étant détectés à partir IE / Registre / Somewhere lent?

Essayez de régler webClient.Proxy = null (ou spécifier les paramètres dans app.config) et votre période de "blocage" devrait être minime.

vous font pression sur F5 ou CTRL + F5 pour l'exécuter? Avec F5 il y a un délai pour VS juste pour rechercher les symboles Async tpLibrary.dll ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top