2011-02-27 3 views
3

J'essaie de comprendre comment fonctionne la nouvelle fonction asynchrone de C# 5. Supposons que je veuille développer une fonction d'incrément atomique pour incrémenter un entier dans un IntStore fictif. Des appels multiples sont faits à cette fonction dans un fil seulement.Comment fonctionne l'async C# 5.0?

async void IncrementKey(string key) { 
    int i = await IntStore.Get(key); 
    IntStore.Set(key, i+1); 
} 

Il me semble que cette fonction est erronée. Deux appels à IncrementKey pourraient récupérer le même nombre de IntStore (disons 5), puis le mettre à 6, perdant ainsi l'un des incréments?

Comment cela peut-il être réécrit, si IntStore.Get est asynchrone (retourne Task) pour fonctionner correctement?

La performance est critique, existe-t-il une solution qui évite le verrouillage?

Répondre

4

Si vous êtes sûr que vous appelez votre fonction à partir d'un seul thread, il ne devrait pas y avoir de problème, car un seul appel à IntStore.Get pourrait être en attente à la fois. Ceci parce que:

await IncrementKey("AAA"); 
await IncrementKey("BBB"); 

la seconde IncrementKey ne sera pas exécutée tant que la première IncrementKey n'aura pas fini. Le code sera converti en une machine d'état. Si vous ne faites pas confiance, changer la IntStore.Get (touche) pour:

async Task<int> IntStore(string str) { 
    Console.WriteLine("Starting IntStore"); 
    await TaskEx.Delay(10000); 
    return 0; 
} 

Vous verrez que le deuxième Starting IntStore sera écrit 10 secondes après la première.

Pour citer ici http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspxThe “await” operator ... means “if the task we are awaiting has not yet completed then sign up the rest of this method as the continuation of that task, and then return to your caller immediately; the task will invoke the continuation when it completes.”