A diferença que o C# 5.0 faz com o async/await
A melhor forma de ver a grande diferença que o async faz é usando exemplos. Saindo de um código não só maior, mas muito mais complicado, com callbacks, tratamento de contexto e thread de execução, tratamento de erros aninhados com os callbacks, pra um código simples, como se fosse um código síncrono comum.
void ShowStuff ()
{
var client = new WebClient ();
var content = JsonValue.Parse (client.DownloadString ("http://api.worldbank.org/countries?format=json&per_page=50"));
int number_of_countries = content [0] ["total"];
int done = 0, error = 0;
InvokeOnMainThread (() => {
CountriesLabel.Text = string.Format ("Countries: {0} done: 0 error: 0", number_of_countries);
});
foreach (JsonObject c in content [1]) {
string country_url = string.Format ("http://api.worldbank.org/countries/{0}/indicators/NY.GDP.MKTP.CD&format=json", (string)c ["id"]);
JsonValue json = null;
try {
json = JsonValue.Parse (client.DownloadString (country_url));
} catch (Exception e){
++error;
InvokeOnMainThread (()=> status.Text = "Got exception "+ e);
continue;
}
ThreadPool.QueueUserWorkItem (delegate {
Map map = null;
try {
map = LoadCountryLogo (c ["name"]).Result;
} catch (Exception e){
++error;
InvokeOnMainThread (()=> status.Text = "Got exception "+ e);
}
if (map != null){
ThreadPool.QueueUserWorkItem (delegate {
Position position = null;
try {
position = LookupCountryPosition (c ["longitude"], c ["latitude"]).Result;
if (position != null)
InvokeOnMainThread (() => {
AddPin (map, position);
++done;
status.Text = json ["name"];
});
} catch (Exception e){
error++;
InvokeOnMainThread (()=> status.Text = "Got exception "+ e);
}
});
}
});
InvokeOnMainThread (() => CountriesLabel.Text = string.Format ("Countries: {0} done: {1} error: {2}", number_of_countries, done, error));
}
InvokeOnMainThread (() => {
CountriesLabel.Text = string.Format ("Countries: {0}", number_of_countries);
});
}
async Task ShowStuffAsync ()
{
var client = new HttpClient ();
var content = JsonValue.Parse (await client.GetStringAsync ("http://api.worldbank.org/countries?format=json"));
int number_of_countries = content [0] ["per_page"];
int done = 0, error = 0;
CountriesLabel.Text = string.Format ("Countries: {0} done: 0 error: 0", number_of_countries);
foreach (JsonObject c in content [1]) {
try {
string country_url = string.Format ("http://api.worldbank.org/countries/{0}/indicators/NY.GDP.MKTP.CD&format=json", (string)c ["id"]);
var json = JsonValue.Parse (await client.GetStringAsync (country_url));
var map = await LoadCountryLogoAsync (json ["name"]);
if (map != null){
var position = await LookupCountryPositionAsync (c ["longitude"], c ["latitude"]);
if (position != null){
AddPin (map, position);
status.Text = json ["name"];
++done;
}
}
} catch (Exception e) {
++error;
status.Text = "Got exception "+ e;
}
CountriesLabel.Text = string.Format ("Countries: {0} done: {1} error: {2}", number_of_countries, done, error);
}
CountriesLabel.Text = string.Format ("Countries: {0}", number_of_countries);
}