À L'Aide De HttpContext.Courant dans WebApi est dangereux en raison de async

Ma question est un peu lié à ce: WebApi équivalent pour HttpContext.Articles avec l'Injection de Dépendance.

Nous voulons injecter une classe à l'aide HttpContext.Courant dans WebApi zone à l'aide de Ninject.

Ma préoccupation est que ce pourrait être très dangereux, comme dans WebApi (tout?) est asynchrone.

S'il vous plaît corrigez-moi si je me trompe dans ces points, c'est ce que j'ai étudié jusqu'à présent:

  1. HttpContext.Actuel devient le contexte actuel par Thread (j'ai regardé dans la mise en œuvre directement).

  2. À L'Aide De HttpContext.Courant à l'intérieur de async Tâche n'est pas possible, car il peut fonctionner sur un autre Thread.

  3. WebApi utilise IHttpController avec la méthode Task<HttpResponseMessage> ExecuteAsync => chaque demande est async => vous ne pouvez pas utiliser HttpContext.Courant à l'intérieur de la méthode d'action. Il pourrait même arriver, plus de requêtes sont exécutées sur le même thread par coicidence.

  4. Pour la création de contrôleurs injectées avec des trucs dans les constructeurs IHttpControllerActivator est utilisé avec sync méthode IHttpController Create. C'est, où ninject crée Contrôleur avec toutes ses dépendances.


  • Si je suis correct dans l'ensemble de ces 4 points, à l'aide de HttpContext.Courant à l'intérieur d'une méthode d'action ou de toute couche ci-dessous est très dangereux et peut avoir des résultats inattendus. J'ai vu sur de SORTE que beaucoup de réponses acceptées ce qui suggère exactement cela. À mon humble avis, cela peut fonctionner pendant un certain temps, mais il ne pourra pas sous la charge.

  • Mais lors de l'utilisation de DI de créer un Contrôleur et de ses dépendances, c'est Ok, parce que cela fonctionne sur un thread séparé. J'ai pu obtenir une valeur de la HttpContext dans le constructeur et il serait à l'abri?. Je me demande si chaque Contrôleur est créé sur un seul thread pour chaque demande, car cela pourrait provoquer un problème de sous de lourdes charges, où tous les threads de IIS peut être consommé.

Juste pour expliquer pourquoi je veux injecter HttpContext trucs:

  • une solution serait de faire la demande dans la méthode d'action de contrôleur et passer à la valeur nécessaire tous les calques en tant que param jusqu'à ce que son utilisé quelque part profondément dans le code.
  • notre voulaient solution: toutes les couches entre ne sont pas afected par cela, et nous pouvons utiliser l'injection de demande de quelque part profondément dans le code (par exemple, dans certains ConfigurationProvider qui dépend de l'URL)

    Merci de me donner votre avis si je suis totalement tort ou mes suggestions sont corrects, ce thème semble être très compliqué. Merci à l'avance!

  • C'est une question très intéressante. Cependant, autant que je sache, si le code ne prévoit pas explicitement de reporter les travaux à un autre thread, les choses seront toujours exécutées sur le même thread. Cela est également vrai pour les tâches asynchrones. Bien que ce ne sera pas bloquer le thread appelant, ça va encore être exécuté sur le thread appelant. Mais je ne suis pas sûr à 100%.. vous devriez l'essayer 😉
  • c'est exactement le problème avec vous attendent pour la plupart rester sur le même fil, mais vous ne pouvez pas être sûr à ce sujet. c'est pourquoi l'OMI tout le monde pense que cela fonctionne, mais va rompre dans des circonstances.. À la Tâche.Courir, c'est bien, c'est un autre thread.
  • pourquoi pensez-vous que vous ne pouvez pas être sûr à ce sujet? Plus que avec une "synchronisation" de la méthode? La méthode de synchronisation peut également exécuter Task.Run(..) ou il pourrait générer un nouveau thread et dans ce thread essayer d'obtenir le HttpContext injecté.. etc. Alors, quelle est la différence?
  • Lorsque vous ne Task.Run, vous le faites par vous-même et vous savez à quoi s'attendre, c'est ok pour moi. Ma préoccupation est,comme la méthode d'action dans webapi est exécutée de manière asynchrone par le cadre, c'est toujours être considéré comme asynchrone avec tous ses pièges. Je pense que, il est même possible, deux Demandes d'exécuter sur le même thread (c'est le but de l'attendent/async je pense) => HttpContext.Courant sera de retour une fausse valeur. En fait, cette question a déjà frappé moi une fois, par la prise de conscience que log4net LogicalThreadContext.Les propriétés ne sont pas de travail en vous connectant WebApi, mais en MVC ils font un travail.
  • Pour answere votre question, pourquoi voudrais-je pense qu'il n'est pas sûr qu'il est en cours d'exécution sur le même fil? - J'ai lu beaucoup d'articles sur internet et il semble que la communauté n'est pas vraiment sûr de cela, mais j'ai eu le sentiment que le SyncronizationContext va décider de commencer à nouveau Thread, ou non, selon les circonstances actuelles, mais practicaly cette situation est très rare. (pas encore sûr à 100% sur ce que beaucoup d'opinions différentes sur internet)
InformationsquelleAutor Lukas K | 2014-07-25