Cierpliwy
(Przemysław Lenart)
April 7, 2024, 7:50pm
1
Hello guys,
Do you know what's the most idiomatic way to offload blocking code to the separate thread or thread pool and get asynchronous function back? I'm looking at equivalent of spawn_blocking from Rust's tokio create. It's important that this method should work also for Linux and Windows.
tera
April 7, 2024, 8:02pm
2
Something like this:
func spawnBlocking<T>(_ execute: @escaping () -> T) async -> T {
await withCheckedContinuation { continuation in
DispatchQueue.global().async {
continuation.resume(returning: execute())
}
}
}
and if the function to execute is throwing:
func spawnBlocking<T>(_ execute: @escaping () throws -> T) async throws -> T {
try await withCheckedThrowingContinuation { continuation in
DispatchQueue.global().async {
continuation.resume(with: Result(catching: execute))
}
}
}
3 Likes
Cierpliwy
(Przemysław Lenart)
April 7, 2024, 9:27pm
3
Thank you for the response!
ibex10
April 7, 2024, 11:36pm
4
Thank you, @tera
But, why does the following code return (Function)
, not the expected numeric result of the computation?
@main
import Foundation
@main
enum AsyncAwaitBlockingCode {
static func main () async throws {
async let u = spawnBlocking {
{() in 17 + 19}
}
await print ("-->", u, u ())
async let v = spawnBlocking_throws {
{() in 23 + 29}
}
try await print ("-->", v, v ())
}
}
func spawnBlocking<T>(_ execute: @escaping () -> T) async -> T {
await withCheckedContinuation { continuation in
DispatchQueue.global().async {
continuation.resume(returning: execute())
}
}
}
func spawnBlocking_throws <T>(_ execute: @escaping () throws -> T) async throws -> T {
try await withCheckedThrowingContinuation { continuation in
DispatchQueue.global().async {
continuation.resume(with: Result(catching: execute))
}
}
}
--> (Function) 36
--> (Function) 52
tera
April 7, 2024, 11:47pm
5
You have a nested closure, is that on purpose? If I got the intention right you want this:
async let u = spawnBlocking { 17 + 19 }
await print ("-->", u)
async let v = spawnBlockingThrows { 23 + 29 }
try await print ("-->", v)