TAP versus EAP

In Windows Phone 7 waren alle async methods via het event asynchronous pattern wat wil zeggen een method waarmee je de actie start en een event wanneer de operatie compleet is. Je ziet dit bijvoorbeeld op de webclient waar je een dergelijke schrijf wijze zou kunnen gebruiken:

public void GetUrl()
        {
            WebClient client = new WebClient();
            client.DownloadStringCompleted += (s, e) =>
                {
                } ;
            client.DownloadStringAsync(new Uri("http://bing.com"))
        }

Met de release van Windows 8 en de nieuwe C# heeft Microsoft de taal C# uitgebreid met 2 nieuwe keywords die ook een nieuwe async pattern "Task Async Pattern" mogelijk maakt. Dit maakt async programmeren veel eenvoudiger, en dat is ook terug te zien in het platform, aanzienlijk meer API's zijn async geworden. Met TAP komt het er zo uit te zien:

public async void GetUrl()
{
    HttpClient client = new HttpClient();
    using (var data = await client.GetStreamAsync(url))
    {
    }
}

De code wijkt vrijwel niet af van wanneer het niet async zou gebeuren behalve het gebruik van async en await keyword. Het is wel async en vraagt nog wel extra aandacht maar dat laat ik hier even buiten beschouwing.

In Windows Phone 8 is Microsoft niet opnieuw begonnen maar zijn er wel heel veel features uit Windows 8 over geheveld naar de Phone, maar ook heel veel API's zo als deze op Windows Phone 7 bestonden. Voor het asynchroon werken betekend het dat we nu gebruik moeten maken van 2 patronen door elkaar, wat ik zelf niet duidelijker op vind worden.

Gelukkig is het eenvoudig om EAP patroon te wrappen in een een TAP versie . Bij deze de oplossing hoe ik het voor de webclient heb gedaan:

public static class WebClientExtensions
    {
        public static Task<string> DownloadStringAsyncTask(this WebClient client, Uri address)
        {
            TaskCompletionSource<string> completionSource = new TaskCompletionSource<string>();
            client.DownloadStringCompleted += client_DownloadStringCompleted;
            client.DownloadStringAsync(address, completionSource);
            return completionSource.Task;
        }

        private static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            WebClient client = (WebClient)sender;
            TaskCompletionSource<string> completionSource = (TaskCompletionSource<string>)e.UserState;

            client.DownloadStringCompleted -= client_DownloadStringCompleted;
            try
            {
                completionSource.SetResult(e.Result);
            }
            catch(Exception ex)
            {
                completionSource.SetException(ex);
            }
        }
    }

 

  •   having a fun afternoon with #fluent and #rome ; let see if can make something publishable
  •   RT @pag3rd: If you'll be at #MSIgnite and want to learn about what's new with #XAML #FluentDesign and the brand new #WinUI library come to…
  •   RT @kevintgallo: What’s your favorite color? https://t.co/GvhJIb4ItX
  •   @shanselman @tomasrestrepo @h0x0d @joncaves does it mean @satyanadella holds the mic for you next time at build?
  •   @BNR De eindstand (aangekomen op bestemming) https://t.co/DXxHPP57iy
  •   Toch even aan die conditie werken.. Je weet maar nooit @bnr #fiemibo https://t.co/H61vOPrtVi
  •   RT @donasarkar: Hello #WindowsInsiders we have released 19H1 Build 18242 to Skip Ahead! https://t.co/kuo5Y9jt0i
  •   @BNR Zines de 2 jaar dat ik bij bnr heb gewerkt 😊 #ikhoorbijbnr
  •   @JenMsft is there a way to get notfication mirring from android to win desktop without the cortana app (its not available in netherlands)
  •   @tomverhoeff @bartlannoeye i agree with bart in this.. been seeing enough 'good speakers' just delivering 101 sessions all the time