> 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