Question

Microsoft a annoncé la Visual Studio Async CTP aujourd'hui (28 Octobre, 2010) qui présente les mots-clés async et await en C # / VB pour l'exécution de la méthode asynchrone.

D'abord, je pense que le compilateur traduit les mots clés dans la création d'un fil, mais selon le papier blanc et Anders Hejlsberg présentation PDC (à 31:00) l'opération asynchrone se produit complètement sur le thread principal.

Comment puis-je avoir une opération exécutée en parallèle sur le même fil? Comment est-il techniquement possible et à ce qui est la caractéristique en fait traduit en IL?

Était-ce utile?

La solution

Il fonctionne de façon similaire au mot-clé yield return en C # 2.0.

Une méthode asynchrone ne sont pas en fait une méthode séquentielle ordinaire. Il est compilé dans une machine d'état (un objet) avec un état (variables locales sont transformées en champs de l'objet). Chaque bloc de code entre deux utilisations de await est une « étape » de la machine d'état.

Cela signifie que lorsque la méthode démarre, il exécute uniquement la première étape, puis le retour de machine d'état et les horaires du travail à faire - lorsque le travail est fait, elle se déroulera l'étape suivante de la machine d'état. Par exemple le code suivant:

async Task Demo() { 
  var v1 = foo();
  var v2 = await bar();
  more(v1, v2);
}

sera traduit à quelque chose comme:

class _Demo {
  int _v1, _v2;
  int _state = 0; 
  Task<int> _await1;
  public void Step() {
    switch(this._state) {
    case 0: 
      this._v1 = foo();
      this._await1 = bar();
      // When the async operation completes, it will call this method
      this._state = 1;
      op.SetContinuation(Step);
    case 1:
      this._v2 = this._await1.Result; // Get the result of the operation
      more(this._v1, this._v2);
  }
}

La partie importante est qu'il utilise juste la méthode SetContinuation de préciser que lorsque les finalise de fonctionnement, il doit appeler la méthode Step à nouveau (et la méthode sait qu'il doit exécuter le second bit du code d'origine en utilisant le champ _state) . Vous pouvez facilement imaginer que le SetContinuation serait quelque chose comme btn.Click += Step, ce qui irait complètement sur un seul thread.

Le modèle de programmation asynchrone en C # est très proche de F # workflows asynchrones (en fait, il est essentiellement la même chose, à part quelques détails techniques), et l'écriture d'applications GUI monothread réactive à l'aide async est tout à fait une zone intéressante - au moins je le crois - voir par exemple cet article (peut-être que je devrais écrire une version C # maintenant: -))

.

La traduction est similaire à itérateurs (et yield return) et en fait, il était possible d'utiliser itérateurs pour mettre en œuvre la programmation asynchrone en C # plus tôt. J'ai écrit un article à ce sujet il y a quelque temps - et je pense que cela peut vous donner encore un peu un aperçu sur la façon dont les travaux de traduction.

Autres conseils

  

Comment puis-je avoir une opération exécutée en parallèle sur le même fil?

Vous ne pouvez pas. asynchronisme n'est pas "parallélisme" ou "la concurrence" . Asynchronisme peut être mis en œuvre avec le parallélisme, ou peut-être pas. Il pourrait être mis en œuvre en brisant le travail en petits morceaux, mettre chaque morceau de travail sur une file d'attente, puis l'exécution de chaque morceau de travail chaque fois que le fil arrive à ne pas faire quoi que ce soit d'autre.

J'ai une série d'articles sur mon blog sur la façon dont tout ça fonctionne; celui qui est directement germane à cette question sera probablement jeudi de la semaine prochaine. Regarder

http://blogs.msdn.com/b/ericlippert/archive / tags / async /

pour plus de détails.

Si je comprends bien, ce que le async et les mots-clés await faire est que chaque fois qu'une méthode async utilise le mot-clé await, le compilateur tourner le reste de la méthode dans une poursuite qui est prévue lorsque l'opération asynchrone est terminée. Cela permet des méthodes de async de retourner immédiatement à l'appelant et de reprendre le travail lorsque la partie async est fait.

Selon les documents disponibles il y a un détail du lot à, mais à moins que je me trompe, qui est l'essentiel.

Comme je le vois dans le but des méthodes async est de ne pas courir beaucoup de code en parallèle, mais pour hacher les méthodes async dans un certain nombre de petits morceaux, qui peut être appelé au besoin. Le point clé est que le compilateur va gérer tout le câblage complexe de tâches à l'aide callbacks / continuations. Cela réduit non seulement la complexité, mais permet la méthode async à écrire plus ou moins comme code synchrone traditionnel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top