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

 

  •   RT @windowsblog: Windows Template Studio 1.1 released! https://t.co/qCLpESAvnB
  •   @JenMsft and does sqrt(4) - 2 gives now the right awnser?
  •   @Alex_A_Simons any updates on that what more is happening ? (2/2)
  •   @Alex_A_Simons long time ago you said the mess between msa and aad's would be fixed; first step was block to create msa on aad account. (1/2
  •   First pullrequest for https://t.co/5lEHH630Io :)
  •   @qmatteoq whosdown is great alternative for whatapps and comes from the store
  •   @jvintzel only for windows 10 s users or can other surface users get it too?
  •   RT @JenMsft: O hi there @Spotify 😊 #Windows10 https://t.co/nlJUgM7vVG https://t.co/boah802WgZ
  •   RT @tvgrimbergen: Awesome! Just extended our @MicrosoftTeams bot. Provide natural language input to initiate a leave request powered by @Ni…
  •   @lancewmccarthy kind of sad :/