> On 11 Sep 2017, at 10:04 pm, Adam Kemp via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
> 
>> On Sep 11, 2017, at 1:15 PM, Kenny Leung via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> I found a decent description about async/await here:
>> 
>> https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
>> 
>> So it’s much more like runloop based callbacks in Foundation that 
>> libdispatch. It’s complicated. Even the simplest example is super 
>> complicated. 
>> 
>> It’s super implicit (like, “I’m going to package up every line of code from 
>> await to the end of this function and turn it into a continuation”). That 
>> seems to go against one of the primary principles of Swift, which is to make 
>> things plain to the reader. I’d be interested to know what the call stack 
>> looks like on the line after await.
> 
> This is pretty much how it would have to work for Swift as well. The call 
> stack after the await (in C#) would either start at the runloop and go 
> through the futures API (usually Task) or it would start at whatever code 
> satisfied the async request.
> 
> It’s true that this can make it more difficult to understand stack traces. In 
> most cases the original call stack is lost. Microsoft has made changes to 
> Visual Studio in order to show kind of an alternative stack trace for tasks 
> to try to make this better.

just FYI, Xcode does that too these days. If you breakpoint/crash within 
something that got asynchronously dispatched, you'll see a synthesised stack 
frame that shows you where it got enqueued from. The same could be done for 
async/await.


> I think they also made things like F10 (step over) and F11 (step out) do the 
> natural thing (i.e., wait for the continuation).
> 
>> 
>> The doc takes away some of the mystery, but leaves major questions, like: 
>> await is used to yield control to the parent, but at the bottom of the call 
>> stack, presumably you’re going to do something blocking, so how do you call 
>> await?
> 
> One of the common misconceptions about async/await (which I also had when I 
> first encountered it) is that there must be a blocking thread somewhere. It 
> doesn’t work that way. The “bottom of the call stack” is typically either a 
> run loop or a thread pool with a work queue (really just another kind of run 
> loop). I guess you’re right in the sense that those kinds of run loops do 
> block, but they’re not blocking on any particular piece of work to be done. 
> They’re blocking waiting for ANY more work to be done (either events or items 
> placed in the work queue).
> 
> The way that the continuation works is that it is placed onto one of those 
> queues. For the UI thread it’s kind of like doing 
> performSelectorOnMainThread: (the .Net equivalent is usually called 
> BeginInvokeOnMainThread). For a thread pool there’s another API. For GCD this 
> would be like doing a dispatch_async. It’s putting the continuation callback 
> block onto a queue, and that callback will be called when the run loop or the 
> thread pool is able to do so.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to