Dlaczego jest HttpContext.Aktualne null po oczekiwaniu?
Mam następujący testowy kod WebAPI, nie używam WebAPI w produkcji, ale zrobiłem to z powodu dyskusji, którą miałem na to pytanie: WebAPI async pytanie
Tak czy inaczej, oto metoda WebAPI:
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";
}
Wierzyłem, że drugi wyjątek jest oczekiwany, ponieważ gdy await
zakończy się, prawdopodobnie będzie na innym wątku, gdzie {[2] } jako zmienna statyczna wątku nie będzie już rozwiązywać do odpowiedniej wartości. Teraz, na podstawie kontekst synchronizacji, faktycznie może być zmuszony do powrotu do tego samego wątku po oczekiwaniu, ale nie robię nic fantazyjnego w moim teście. Jest to po prostu proste, naiwne użycie await
.
W komentarzach do innego pytania powiedziano mi, że HttpContext.Current
powinno się rozwiązać po oczekiwaniu. Jest jeszcze jeden komentarz na to pytanie, wskazujący na to samo. Więc co jest prawdą? Czy powinno się rozwiązać? Myślę, że nie, ale chcę autorytatywnej odpowiedzi na to, ponieważ async
i await
jest na tyle Nowa, że nie mogę znaleźć cokolwiek definitywnego.
TL;DR: czy HttpContext.Current
potencjalnie null
po await
?
3 answers
Upewnij się, że piszesz ASP.NET 4.5 aplikacji, a kierowanie 4.5. async
i await
mają nieokreślone zachowanie na ASP.NET chyba że używasz 4.5 i używasz nowego kontekstu synchronizacji "przyjaznego dla zadań".
W szczególności oznacza to, że musisz:
- Ustaw
httpRuntime.targetFramework
na4.5
, lub - w Twoim
appSettings
Ustawaspnet:UseTaskFriendlySynchronizationContext
natrue
.
Więcej informacji jest dostępne tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-23 11:22:08
Jak słusznie zauważył @ StephenCleary, potrzebujesz tego w swojej sieci.config:
<httpRuntime targetFramework="4.5" />
Kiedy po raz pierwszy rozwiązywałem ten problem, przeprowadziłem szeroko zakrojone poszukiwania powyższego rozwiązania, potwierdziłem, że jest on obecny we wszystkich moich projektach internetowych i szybko odrzuciłem go jako winowajcę. W końcu przyszło mi do głowy, aby spojrzeć na te wyniki wyszukiwania w pełnym kontekście:
<!--
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.
Lekcja: jeśli zaktualizujesz projekt sieci web do wersji 4.5, nadal musisz ręcznie wprowadzić to ustawienie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-28 18:16:31
Czy mój test jest wadliwy, Czy jest jakaś sieć.brakuje mi elementu config tutaj zrobiłby HttpContext.Aktualne rozwiązanie poprawnie po czekać?
Twój test nie jest wadliwy i HttpContext.Current nie powinien być null po oczekiwaniu, ponieważ w ASP.NET Web API kiedy czekasz, zapewni to, że kod następujący po tym oczekiwaniu zostanie przekazany poprawnemu Httpcontextowi, który był obecny przed czekaniem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 15:13:42