Vra

Vir een of ander rede is daar 'n pouse na die program onder begin. Ek glo dat WebClient().DownloadStringTaskAsync() is die oorsaak.

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

Sover ek verstaan ??my program moet tel dadelik begin 0-15. Doen ek iets verkeerd?

Ek het dieselfde probleem met die oorspronklike Netflix aflaai monster (wat jy met CTP ) - na die druk op die soek knoppie die UI eerste vries - en na 'n tyd is dit reageer terwyl loadning die volgende films. En ek glo dit nie vries in aanbieding Anders Hejlsberg se PDC 2010.

Nog 'n ding. Wanneer in plaas van

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

Ek gebruik my eie metode:

return await ReturnOrdinaryTask();

Dit is:

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

Dit werk soos dit moet. Ek bedoel dit nie iets te laai, maar dit begin onmiddellik en nie die belangrikste draad te sluit, terwyl doen sy werk.

Edit

OK, wat ek glo nou is: die WebClient.DownloadStringTaskAsync funksie is screwed up. Dit behoort te werk sonder die aanvanklike blokkeer tydperk, soos volg:

    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);
        }
    }
Was dit nuttig?

Oplossing

Terwyl jou program nie blok vir 'n rukkie, dit doen uitvoering CV in die for-lus, voor die gevolg is terug van die afgeleë bediener.

Onthou dat die nuwe asinkroniseer API is nog enkele-threaded. So WebClient().DownloadStringTaskAsync() moet nog uitgevoer word op jou draad totdat die versoek is voorberei en gestuur word aan die bediener, voordat dit kan await en uitvoering opbrengs terug na jou program vloei in Main ().

Ek dink die resultate wat jy sien is te danke aan die feit dat dit 'n geruime tyd om te skep en stuur die versoek uit jou masjien. Eerste wanneer dit klaar is, kan die implementering van DownloadStringTaskAsync wag vir netwerk IO en die afgeleë bediener te voltooi, en kan uitvoer na julle terugkeer.

Aan die ander kant, jou RunOrdinaryTask metode net initialisatie n taak en gee dit 'n werklading, en vertel dit aan begin. Dan terug dit onmiddellik. Dit is waarom jy nie 'n vertraging sien wanneer die gebruik van RunOrdinaryTask.

Hier is 'n paar skakels oor die onderwerp: Eric Lippert se blog (een van die taal ontwerpers ), sowel as Jon kleiduiven se aanvanklike blog post daaroor. Eric het 'n reeks van 5 poste oor-voortsetting verby styl, wat werklik is wat async en await is regtig oor. As jy wil hê dat die nuwe funksie in detail verstaan, wil jy dalk om Eric se poste oor CPS en A-sinkroniseer lees. In elk geval, beide links bo 'n goeie werk op te verduidelik 'n baie belangrike feit:

  • Asynchronous! = Parallel

Met ander woorde, async en await nie spin nuwe drade vir jou. Hulle kan net jy hervat uitvoering van jou normale vloei, wanneer jy doen 'n blokkeer operasie -. Keer waar jou CPU net sou sit en niks doen nie in 'n sinkrone program, wag vir 'n paar eksterne werking te voltooi

Edit

Net om duidelik te wees oor wat gebeur wees: DownloadStringTaskAsync stel 'n voortsetting, dan doen 'n beroep WebClient.DownloadStringAsync, op dieselfde draad, en dan opbrengste uitvoering terug na jou kode. Daarom is die blokkering keer as jy sien voordat die lus begin tel, is die tyd wat dit neem DownloadStringAsync te voltooi. Jou program met asinkroniseer en wag vir is baie geheg die ekwivalent van die volgende program, wat dieselfde gedrag as jou program vertoon word: 'n Aanvanklike blok, dan tel begin, en iewers in die middel, die asinkroniseer op afwerkings en die inhoud van druk die versoek 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);
        }
    }

Let wel: Ek is geensins 'n kenner op die onderwerp, so ek verkeerd oor 'n paar punte kan wees. Voel vry om my begrip van die onderwerp korrek, as jy dink dit is verkeerd -. Ek het net gekyk na die PDC aanbieding en gespeel met die CTP gisteraand

Ander wenke

Is jy seker die kwessie is nie verband hou met die volmag konfigurasie-instellings ontdek van Internet Explorer / Register / Iewers Slow?

Jy kan probeer om webClient.Proxy = null (of spesifiseer instellings in app.config) en jou "blokkeer" tydperk moet minimaal wees.

Is jy druk F5 of CTLR + F5 om dit uit te voer? Met F5 daar is 'n vertraging vir VS net om te soek na die simbole vir AsyncCtpLibrary.dll ...

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top