Question Pourquoi HttpContext.Current est-il nul après attente?


J'ai le code WebAPI de test suivant, je n'utilise pas WebAPI en production mais je l'ai fait à cause d'une discussion sur cette question: Question Async WebAPI

Quoi qu'il en soit, voici la méthode WebAPI incriminée:

public async Task<string> Get(int id)
{
    var x = HttpContext.Current;
    if (x == null)
    {
        // not thrown
        throw new ArgumentException("HttpContext.Current is null");
    }

    await Task.Run(() => { Task.Delay(500); id = 3; });

    x = HttpContext.Current;
    if (x == null)
    {
        // thrown
        throw new ArgumentException("HttpContext.Current is null");
    }

    return "value";
}

Je pensais que la deuxième exception est attendue car lorsque le await complète, il sera probablement sur un thread différent où HttpContext.Current comme une variable thread-statique ne sera plus résoudre à la valeur appropriée. Maintenant, en fonction du contexte de synchronisation, il pourrait être forcé de retourner au même thread après l’attente, mais je ne fais rien de compliqué dans mon test. Ceci est juste une utilisation simple et naïve de await.

Dans les commentaires d'une autre question, on m'a dit que HttpContext.Current devrait résoudre après une attente. Il y a même un autre commentaire sur cette question qui indique la même chose. Alors qu'est-ce qui est vrai? Devrait-il résoudre? Je pense que non, mais je veux une réponse officielle à ce sujet parce que async et await est assez nouveau pour que je ne puisse rien trouver de définitif.

TL; DR: Est-ce que HttpContext.Current potentiellement null après un await?


72
2017-08-22 14:53


origine


Réponses:


Veuillez vous assurer que vous écrivez un ASP.NET 4.5 application et ciblage 4.5. async et await avoir un comportement indéfini sur ASP.NET sauf si vous utilisez 4.5 et utilisent le nouveau contexte de synchronisation "adapté aux tâches".

En particulier, cela signifie que vous devez soit:

  • Ensemble httpRuntime.targetFramework à 4.5, ou
  • Dans ton appSettings, ensemble aspnet:UseTaskFriendlySynchronizationContext à true.

Plus d'informations sont disponible ici.


116
2017-08-22 15:06



Comme @StephenCleary l'a souligné correctement, vous en avez besoin dans votre fichier web.config:

<httpRuntime targetFramework="4.5" />

Lors de mon premier dépannage, j'ai effectué une recherche dans toute la solution pour ce qui précède, a confirmé sa présence dans tous mes projets Web et l’a rapidement rejetée comme coupable. En fin de compte, je me suis penché sur ces résultats de recherche dans leur contexte:

<!--
  For a description of web.config changes for .NET 4.5 see http://go.microsoft.com/fwlink/?LinkId=235367.

  The following attributes can be set on the <httpRuntime> tag.
    <system.Web>
      <httpRuntime targetFramework="4.5" />
    </system.Web>
-->

Doh.

Leçon: Si vous mettez à niveau un projet Web vers la version 4.5, vous devez toujours définir ce paramètre manuellement.


18
2018-01-28 18:16



Est-ce que mon test est défectueux ou y a-t-il un élément web.config qui me manque?   ici qui ferait résoudre HttpContext.Current correctement après une   attendre?

Votre test n'est pas défectueux et HttpContext.Current ne doit pas être nul après l'attente car, dans l'API Web ASP.NET, vous attendez que le code suivant apparaisse avant l'attente.


3
2017-08-22 14:58