Frage

Aus irgendeinem Grund gibt es eine Pause nach dem Programm unten beginnt. Ich glaube, dass WebClient().DownloadStringTaskAsync() die Ursache ist.

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"));
    }
}

Soweit ich mein Programm verstehen sollte das Zählen von 0 bis 15 sofort starten. Bin ich etwas falsch zu machen?

Ich hatte das gleiche Problem mit der ursprünglichen Download Probe Netflix (die Sie erhalten mit CTP ) - nach der Suchtaste der UI zuerst gefrieren drücken - und nach einiger Zeit ist es anspricht, während die nächsten Filme loadning. Und ich glaube, es ist nicht Präsentation in Anders Hejlsberg DID gefror bei PDC 2010.

Eine weitere Sache. Wenn anstelle von

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

Ich verwende meine eigene Methode:

return await ReturnOrdinaryTask();

Welche ist:

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;
}

Es funktioniert, wie es sollte. Ich meine, es hat nichts zu laden, aber es startet sofort und blockiert nicht den Haupt-Thread, während seine Arbeit zu tun.

Bearbeiten

OK, was ich glaube, jetzt ist: die WebClient.DownloadStringTaskAsync Funktion vermasselt. Es sollte ohne die erste Sperrfrist arbeiten, wie folgt aus:

    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);
        }
    }
War es hilfreich?

Lösung

Während Ihr Programm tut Block für eine Weile, es tut Lebenslauf Ausführung in dem for-Schleife, bevor das Ergebnis von dem Remote-Server zurückgegeben wird.

Beachten Sie, dass der neue async API noch single-threaded ist. So WebClient().DownloadStringTaskAsync() muss noch auf dem Thread ausgeführt, bis die Anfrage an den Server vorbereitet wurde und gesendet wird, bevor es zu einem Programmablauf in Main () await und Ertrag Ausführung zurück kann.

Ich denke, die Ergebnisse, die Sie sehen auf die Tatsache zurückzuführen ist, dass es einige Zeit dauert, die Anfrage aus Ihrem Gerät zu erstellen und zu senden. Erst wenn das abgeschlossen ist, kann die Implementierung von DownloadStringTaskAsync für Netzwerk-IO warten und der Remote-Server abgeschlossen und kann die Ausführung zu Ihnen zurück.

Auf der anderen Seite, Ihre RunOrdinaryTask Methode initialisiert nur eine Aufgabe und gibt ihm eine Arbeitsbelastung, und sagt es zu starten. Dann kehrt es sofort. Deshalb sollten Sie keine Verzögerung sehen, wenn RunOrdinaryTask verwendet wird.

Hier sind einige Links zum Thema: Eric Lippert Blog (einer der Sprachdesigner ) sowie Jon Skeet anfängliche Blog-Post darüber. Eric hat eine Serie von 5 Beiträge über Fortsetzung-Passing-Stil, der wirklich ist, was async und await wirklich ist. Wenn Sie die neue Funktion im Detail verstehen wollen, möchten Sie vielleicht Erics Beiträge über CPS und Async lesen. Wie auch immer, tun beiden Links oben einen guten Job eine sehr wichtige Tatsache zu erklären:

  • Asynchronous! = Parallel

Mit anderen Worten, async und await keine neuen Threads für Sie spin up. Sie nur können Sie die Ausführung Ihres normalen Flusses wieder aufnehmen, wenn Sie einen Sperrbetrieb tun -. Zeiten, in denen Sie Ihre CPU würde nur sitzen und nichts tun, in einem synchronen Programm, für einige externe Operation vollständig warten

Bearbeiten

Just klar zu sein über das, was geschieht: DownloadStringTaskAsync setzt auf eine Fortsetzung, dann ruft WebClient.DownloadStringAsync, auf dem gleichen Thread, und und Erträge Ausführung zurück zu Ihrem Code. Daher wird die Sperrzeit Sie sehen werden, bevor die Schleifenzählung beginnt, ist die Zeit, es DownloadStringAsync in Anspruch nimmt. Ihr Programm mit async und await ist ganz in der Nähe das Äquivalent des folgenden Programms sein, die das gleiche Verhalten wie das Programm zeigt: Ein ersten Block, dann beginnt mit dem Zählen, und irgendwo in der Mitte, die Asynchron-op Oberflächen und drucken den Inhalt von die angeforderte URL:

    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);
        }
    }

Hinweis: Ich bin keineswegs ein Experte zu diesem Thema, so dass ich in einigen Punkten falsch sein könnte. Fühlen Sie sich frei, mein Verständnis des Themas zu korrigieren, wenn Sie denken, das ist falsch. - Ich nur an der PDC Präsentation sah und mit der CTP gestern Abend gespielt

Andere Tipps

Sind Sie sicher, dass das Problem nicht auf die Proxy-Konfigurationseinstellungen verwendet sind von IE / Registry / Irgendwo erkannt wird langsam?

Versuchen Sie, webClient.Proxy = null (oder Einstellungen in app.config Angabe) und Ihre "Sperrung" Zeit sollte minimal sein.

drücken Sie F5 oder CTLR + F5, um sie auszuführen? Mit F5 gibt es eine Verzögerung für VS nur für die Symbole für AsyncCtpLibrary.dll suchen ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top