Dernièrement, je n'arrive pas à en avoir assez de l'incroyable motif asynchrone de C # 5.0. Où étais-tu, durant toute ma vie?
Je suis absolument ravi de la syntaxe simple, mais j'ai une petite difficulté. Mon problème est que les fonctions asynchrones ont une déclaration totalement différente des fonctions régulières. Étant donné que seules les fonctions asynchrones peuvent attendre sur d'autres fonctions asynchrones, lorsque j'essaie de porter un ancien code de blocage vers async, j'ai un effet domino des fonctions que je dois convertir.
Les gens ont appelé cela une infestation de zombies . Lorsque async obtient une morsure dans votre code, il ne cesse de s'agrandir. Le processus de portage n'est pas difficile, il suffit de jeter async
la déclaration et d'envelopper la valeur de retour avec Task<>
. Mais il est ennuyeux de le faire encore et encore lors du portage de l'ancien code synchrone.
Il me semble que ce sera beaucoup plus naturel si les deux types de fonctions (async et plain old sync) avaient exactement la même syntaxe. Si tel était le cas, le portage ne demanderait aucun effort et je pourrais basculer sans douleur entre les deux formes.
Je pense que cela pourrait fonctionner si nous suivons ces règles:
Les fonctions asynchrones ne nécessiteront plus la
async
déclaration. Leurs types de retour n'auraient pas à être enveloppésTask<>
. Le compilateur identifiera lui-même une fonction asynchrone pendant la compilation et effectuera automatiquement l'enveloppement de la tâche <> selon les besoins.Plus besoin de tirer et d'oublier les fonctions asynchrones. Si vous souhaitez appeler une fonction asynchrone, vous devrez l'attendre. J'utilise à peine le feu et oublie de toute façon, et tous les exemples de conditions de course folles ou de blocages semblent toujours être basés sur eux. Je pense qu'ils sont trop confus et «déconnectés» de l'état d'esprit synchrone que nous essayons de tirer parti.
Si vous ne pouvez vraiment pas vivre sans tirer et oublier, il y aura une syntaxe spéciale pour cela. En tout cas, cela ne fera pas partie de la simple syntaxe unifiée dont je parle.
Le seul mot-clé dont vous avez besoin pour désigner un appel asynchrone est
await
. Si vous avez attendu, l'appel est asynchrone. Si vous ne le faites pas, l'appel est tout simplement synchrone (rappelez-vous, nous n'avons plus le feu et oublions).Le compilateur identifiera automatiquement les fonctions asynchrones (car elles n'ont plus de déclaration spéciale). La règle 4 rend cela très simple à faire - si une fonction a un
await
appel à l'intérieur, c'est async.
Cela pourrait-il fonctionner? ou est-ce que je manque quelque chose? Cette syntaxe unifiée est beaucoup plus fluide et pourrait résoudre complètement l'infestation de zombies.
Quelques exemples:
// assume this is an async function (has await calls inside)
int CalcRemoteBalanceAsync() { ... }
// assume this is a regular sync function (has no await calls inside)
int CalcRemoteBalance() { ... }
// now let's try all combinations and see what they do:
// this is the common synchronous case - it will block
int b1 = CalcRemoteBalance();
// this is the common asynchronous case - it will not block
int b2 = await CalcRemoteBalanceAsync();
// choosing to call an asynchronous function in a synchronous manner - it will block
// this syntax was used previously for async fire-and-forget, but now it's just synchronous
int b3 = CalcRemoteBalanceAsync();
// strange combination - it will block since it's calling a synchronous function
// it should probably show a compilation warning though
int b4 = await CalcRemoteBalance();
Remarque: il s'agit d'une continuation d'une discussion connexe intéressante dans SO
await
immédiatement. Vous pouvez faire quelque chose comme ça var task = FooAsync(); Bar(); await task;
. Comment pourrais-je procéder dans votre proposition?
async
. Je pense que c'est l'un des grands avantages de async
- await
: qu'il vous permet de composer facilement des opérations asynchrones (et pas seulement de la manière la plus simple "démarrer A, attendre A, démarrer B, attendre B"). Et il existe déjà une syntaxe spéciale à cet effet: elle s'appelle await
.