Async method runs sync on caller context/thread until its execution path runs into an I/O or similar task which has some waiting involved and then, instead of waiting, it returns to original caller, resuming its continuation later. The question is, what is the preferred way of implementing that "wait" method. How do the File/Network/etc async methods do it?
Lets assume I have a method which will have some waiting involved which is not covered by current IOs out of the box. I do not want to block calling thread and I do not want to force my caller to do a Task.Run()
to offload me, I want a clean async/await pattern so that my callers can seamlessly integrate my library and I can run on its context until such time I need to yield. Lets for the sake of argument assume that I want to make a new IO lib which is not covered and I need a way to make all the glue that keeps async together.
Do I Task.Yield
and continue? Do I have to do my own Task.Run
/Task.Wait
, etc? Both seem like more of the same abstractions (which brings the question how does Yield
yield). I am curious, because there is a lot of talk about how async/await continuation works for the consumer and how all IO libs come already prepped, but there is very little about how the actual "breaking" point works and how process makers should implement it. How does the code at the end of a sync path actually release control and how the method operates at that point and after.