[C#] Async CTP: parallel await?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Hyperz
  • Registratie: Augustus 2009
  • Laatst online: 09-07 02:45
Hey :).

Om maar met de deur in huis te vallen: is het mogelijk om meerdere tasks in parallel te awaiten? Neem nu dit simpel voorbeeld:

C#:
1
2
3
4
5
6
7
8
9
public async void PrintAllPagesAsync(string[] urls)
{
    IEnumerable<Task<string>> tasks = urls.Select(url => DownloadPageAsync(url));

    foreach (Task<string> task in tasks)
    {
        Console.WriteLine(await task);
    }
}


Dit werkt perfect. Het blockt de UI thread niet en de WriteLine functie wordt aangeroepen in de UI thread. Allemaal mooi, maar het probleem is dat het awaiten in die foreach loop niet in parallel gebeurd. Ik dacht dat indien de eerste task nog niet klaar was, hij direct naar de tweede task zou gaan enz. Ik zou een Parallel.ForEach loop kunnen gebruiken of een de thread pool maar dan moet ik terug beginnen invoken enzo voor zover ik weet.

Weet iemand of (en hoe) dit kan opgelost worden in Async CTP (zonder dus terug te moeten vallen op de oude manier (invoke))? Alvast bedankt.

Asus P8P67 EVO | i5 2500k (4.8 GHz) | Sapphire HD 7970 Vapor-X GHz Ed. | 8 GB DDR3 1600 | 1 TB HDD


Acties:
  • 0 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:29
Niet getest en ik zit er niet zo goed in, maar zou dit niet werken?

C#:
1
2
3
4
5
6
7
8
public async void  PrintAllPagesAsync(string[] urls)
    {
        urls.ForEach(url => 
        {
           Console.WriteLine(await  DownloadPageTaskAsync(url));
        }
    ); 
}


waar DownloadPageTaskAsync dus een task teruggeeft..

[ Voor 15% gewijzigd door Caelorum op 12-08-2011 17:58 . Reden: duh.. foreach ipv select ^^ ]


Acties:
  • 0 Henk 'm!

  • Hyperz
  • Registratie: Augustus 2009
  • Laatst online: 09-07 02:45
Het werkt in een console app, maar WriteLine wordt dan niet aangeroepen in de UI thread. In een WinForms app werkt het niet parallel.

Asus P8P67 EVO | i5 2500k (4.8 GHz) | Sapphire HD 7970 Vapor-X GHz Ed. | 8 GB DDR3 1600 | 1 TB HDD


Acties:
  • 0 Henk 'm!

  • Feanathiel
  • Registratie: Juni 2007
  • Niet online

Feanathiel

Cup<Coffee>

Hyperz schreef op vrijdag 12 augustus 2011 @ 18:59:
Het werkt in een console app, maar WriteLine wordt dan niet aangeroepen in de UI thread. In een WinForms app werkt het niet parallel.
Dat kun je wellicht oplossen door gebruik te maken van Invoke(). InvokeRequired lijkt mij hier niet van toepassing, omdat het uitvoeren van de parallelle taken altijd op een andere thread wordt uitgevoerd. Een voorbeeld kan bijvoorbeeld het volgende zijn, al vind ik het er persoonlijk niet leesbaarder op worden:

C#:
1
2
3
4
5
6
7
8
9
10
public async void PrintAllPagesAsync(string[] urls) 
{ 
    urls.ForEach(url => {
        string message = await DownloadPageTaskAsync(url);

        Invoke( new Action () => {
            Console.WriteLine( message );
        });
    });  
}


Notitie: let er dus op dat je niet await in de Action die je daar aan maakt.

[ Voor 9% gewijzigd door Feanathiel op 13-08-2011 09:31 ]


Acties:
  • 0 Henk 'm!

  • Hyperz
  • Registratie: Augustus 2009
  • Laatst online: 09-07 02:45
Dat weet ik, maar dat is juist het mooie van async/await, dat je die invoke rommel niet meer hoeft te doen. Als ik moet gaan invoken kan ik net zo goed een gewone thread aanmaken of de thread pool gebruiken ;).

Asus P8P67 EVO | i5 2500k (4.8 GHz) | Sapphire HD 7970 Vapor-X GHz Ed. | 8 GB DDR3 1600 | 1 TB HDD


Acties:
  • 0 Henk 'm!

Verwijderd

Je kunt een overkoepelende task maken met WhenAll.

string[] strings = await TaskEx.WhenAll(tasks);

(mocht er nog iemand kijken)
Pagina: 1