Personal computing discussed

Moderators: SecretSquirrel, just brew it!

 
derFunkenstein
Gold subscriber
Gerbil God
Topic Author
Posts: 24699
Joined: Fri Feb 21, 2003 9:13 pm
Location: Comin' to you directly from the Mothership

Swift 5: async/await pattern

Sat Aug 18, 2018 12:15 pm

I might be the only person on TR excited about this. Mostly because at work everything I write is in C# in the form of a Xamarin Forms app, and as far as modern programming languages go, C# is where I'm (by far) the most proficient. As a hobby I've picked up a bit in both Swift (for iOS / Mac apps) and Java/Kotlin for Android apps. There'll be two responses to this thread: "meh" or "Funk, you're an idiot" and I don't mind. It gives you an opportunity to correct me and I won't even get offended. :D

So since I started with C# and then moved to these native platforms, I got to learn about something that's either optional or non-existent in C# (probably the former): completion handlers. Want to write a method that calls a handful of web services? Get used to completion handlers. It works way differently than I am used to and while I'm getting a handle on it, it's not fun. I *really* like async and await in C#. Create a bunch of tasks, call Task.WhenAll and the method stops until those tasks are all complete.

It's one of those things that makes my Xamarin Forms app faster than anything I've written in Xcode, because I can't figure out how to best call three different web services to get all the data I need simultaneously and then move on with the rest of the function. That's probably just me not knowing how to do it correctly rather than a limitation of the language. The example code towards the end of section 2 on this page is a great example of what I'm talking about.

Last year it was codables that turn JSON strings into objects natively, and this time it's async/await. Just in time for the smartphone to die, amirte?
I do not understand what I do. For what I want to do I do not do, but what I hate I do.
 
nico1982
Gold subscriber
Gerbil
Posts: 38
Joined: Fri Jan 29, 2010 7:30 am

Re: Swift 5: async/await pattern

Sat Aug 18, 2018 1:11 pm

I'm not really familiar with C# async/await and my iOS skills are a bit rusty now, but I'd take a look at dispatch_group.
 
derFunkenstein
Gold subscriber
Gerbil God
Topic Author
Posts: 24699
Joined: Fri Feb 21, 2003 9:13 pm
Location: Comin' to you directly from the Mothership

Re: Swift 5: async/await pattern

Sat Aug 18, 2018 9:24 pm

nico1982 wrote:
I'm not really familiar with C# async/await and my iOS skills are a bit rusty now, but I'd take a look at dispatch_group.

That looks like it may help. Kick off all the members of the group, wait for notification about everything being done, and the listener can kick off updating the UI. It should at least let me make all the web API calls that I want to make all at once. Seemed like a common sort of thing, but I just couldn't put the Google terms together to figure it out. Happens sometimes. I appreciate the reply, because I learned something. :)

edit...this code block looks like it would do exactly what I was looking for. Setting a timeout to continue the best way possible if everything doesn't complete in a reasonable timeframe seems like a smart move, too.

let dispatchGroup = DispatchGroup()

dispatchGroup.enter()
longRunningFunction { dispatchGroup.leave() }

dispatchGroup.enter()
longRunningFunctionTwo { dispatchGroup.leave() }

dispatchGroup.wait(timeout: 10)

//update the UI


That kind of looks like it could block on the main thread, though. I can do Task.Run or Task.WhenAll to spin off my own threads in C# without locking the main thread (where the spinner can keep spinning unimpeded). It seems like you can do the same thing in Swift with an async function call.
I do not understand what I do. For what I want to do I do not do, but what I hate I do.
 
Duct Tape Dude
Gerbil Elite
Posts: 711
Joined: Thu May 02, 2013 12:37 pm

Re: Swift 5: async/await pattern

Sat Aug 18, 2018 11:53 pm

derFunkenstein wrote:
That kind of looks like it could block on the main thread, though. I can do Task.Run or Task.WhenAll to spin off my own threads in C# without locking the main thread (where the spinner can keep spinning unimpeded). It seems like you can do the same thing in Swift with an async function call.
Unless I'm misunderstanding Swift's implementation, I think you're conflating parallel vs async execution.

C#'s Task.Run() et al. spawn multiple threads and shares memory as needed to complete a task. Your code gets executed in a different thread and the results are reported back to the main thread, with appropriate memory sharing etc done under the hood by the .NET engine.

Async functions always run on the same thread, but anytime the program is idly waiting for something to execute (typically I/O), it allows the event loop to process other tasks. This means things like long for() loops will still stall the main thread (unless you explicitly yield periodically), but reading a file from disk or over the network frees your program to do other things (like update a UI).

In general, async is a great model as long as you keep all heavy computation out of it. Running tasks in multiple threads has additional overhead when spawning/destroying threads, hence silly things like fibers and [c,g]oroutines coming into vogue as of late (but those too have their limitations).

Honestly, either model is probably fine until you're in the single to tens of thousands of requests/s.
 
nico1982
Gold subscriber
Gerbil
Posts: 38
Joined: Fri Jan 29, 2010 7:30 am

Re: Swift 5: async/await pattern

Sun Aug 19, 2018 3:30 am

derFunkenstein wrote:
That kind of looks like it could block on the main thread, though.

Yes, wait will block the thread. However, notify returns immediately and accept a block that will be executed when the group is empty.

Who is online

Users browsing this forum: No registered users and 2 guests