Właśnie przetestowałem coś, co na pewno by się nie udało, ale ku mojemu zdziwieniu zadziałało bezbłędnie i udowadniało, że nadal jestem pod wrażeniem tego, jak działa async-await
.Pętla ciała wątku Async, po prostu działa, ale jak?
Utworzono wątek, przekazując delegata async void
jako treść wątku. Oto uproszczeniem mojego kodu:
var thread = new Thread(async() => {
while(true) {
await SomeLengthyTask();
...
}
});
thread.Start();
thread.Join();
Chodzi o to, że o ile mi zrozumieć, gdy wykonanie uderza słowa kluczowego await
istnieje niejawna powrót ze sposobu, w tym przypadku ciało pętli wątku, podczas gdy reszta kodu jest zawijana w kontynuację wywołania zwrotnego.
Z tego powodu byłem pewien, że wątek zakończy się, gdy tylko await
wykona egzekucję, ale tak nie jest!
Czy ktoś wie, jak ta magia jest rzeczywiście realizowana? Czy funkcja async
jest rozebrana i czy async
czeka w sposób synchroniczny, czy też CLR wykonał jakąś czarną magię, która umożliwia jej wznowienie wątku, który powstał z powodu await
?
Dzięki za poprawne wyjaśnienie między lambdą a delegatem, odpowiednio zredagowałem moje pytanie. Tak więc, aby zrozumieć, co właściwie robi CLR, po prostu uniemożliwia się Join() oryginalnego wątku? – BlueStrat
@ BlueStrat Nie, to ma miejsce. Właśnie dlatego dodałem 'Console.ReadLine' w moim przykładzie. Bez niego moja aplikacja konsolowa kończy się przed dotarciem do interesującej części. – i3arnon
@ BlueStrat Nic tu nie robi nic specjalnego. Metody 'async' po prostu nie działają w tym samym wątku. Mogą to zrobić, ale tak długo, jak nie istnieje Kontekst Synchronizacji, uruchamiają każdą synchroniczną część w ThreadPool – i3arnon