CoroutineScheduler
public protocol CoroutineSchedulerA protocol that defines how to execute a task.
This protocol has extension methods that allow to launch coroutines on a current scheduler.
Inside the coroutine you can use such methods as Coroutine.await(_:), CoFuture.await(),
and CoroutineScheduler.await(_:) to suspend the coroutine without blocking a thread
and resume it when the result is ready.
To launch a coroutine, use CoroutineScheduler.startCoroutine(_:).
//execute coroutine on the main thread
DispatchQueue.main.startCoroutine {
    //extension that returns CoFuture<(data: Data, response: URLResponse)>
    let dataFuture = URLSession.shared.dataTaskFuture(for: url)
    //await result that suspends coroutine and doesn't block the thread
    let data = try dataFuture.await().data
}
The framework includes the implementation of this protocol for DispatchQueue
and you can easily make the same for other schedulers as well.
extension OperationQueue: CoroutineScheduler {
    public func scheduleTask(_ task: @escaping () -> Void) {
        addOperation(task)
    }
}
- 
                  
                  Performs the task at the next possible opportunity. DeclarationSwift func scheduleTask(_ task: @escaping () -> Void)
- 
                  startCoroutine(in:Extension methodtask: ) Start a new coroutine on the current scheduler. As an example, with Coroutine.await(_:)you can wrap asynchronous functions with callbacks to synchronously receive its result without blocking the thread.//start new coroutine on the main thread DispatchQueue.main.startCoroutine { //execute someAsyncFunc() and await result from its callback let result = try Coroutine.await { someAsyncFunc(callback: $0) } }DeclarationSwift public func startCoroutine(in scope: CoScope? = nil, task: @escaping () throws -> Void)ParametersscopeCoScopeto add coroutine to.taskThe closure that will be executed inside coroutine. If the task throws an error, then the coroutine will be terminated. 
- 
                  await(_:Extension method) Start a coroutine and await its result. Must be called inside other coroutine. This method allows to execute given task on other scheduler and await its result without blocking the thread. //start coroutine on the main thread DispatchQueue.main.startCoroutine { //execute someSyncFunc() on global queue and await its result let result = try DispatchQueue.global().await { someSyncFunc() } }Throws Rethrows an error from the task or throwsCoroutineError.DeclarationSwift @inlinable public func await<T>(_ task: () throws -> T) throws -> TParameterstaskThe closure that will be executed inside coroutine. Return ValueReturns the result of the task. 
- 
                  coroutineFuture(_:Extension method) Starts a new coroutine and returns its future result. This method allows to execute a given task asynchronously inside a coroutine and returns CoFuturewith its future result immediately.Note If you cancel thisCoFuture, it will also cancel the coroutine that was started inside of it.//execute someSyncFunc() on global queue and return its future result let future = DispatchQueue.global().coroutineFuture { someSyncFunc() } //start coroutine on main thread DispatchQueue.main.startCoroutine { //await result of future let result = try future.await() }DeclarationSwift @inlinable public func coroutineFuture<T>(_ task: @escaping () throws -> T) -> CoFuture<T>ParameterstaskThe closure that will be executed inside the coroutine. Return ValueReturns CoFuturewith the future result of the task.
- 
                  actor(of:Extension methodbufferType: body: ) Starts new coroutine that is receiving messages from its mailbox channel and returns its mailbox channel as a Sender.An actor coroutine builder conveniently combines a coroutine, the state that is confined and encapsulated into this coroutine, and a channel to communicate with other coroutines. Note If you cancel thisCoChannel, it will also cancel the coroutine that was started inside of it.//Message types for actor enum CounterMessages { case increment, getCounter(CoPromise<Int>) } let actor = DispatchQueue.global().actor(of: CounterMessages.self) { receiver in var counter = 0 for message in receiver { switch message { case .increment: counter += 1 case .getCounter(let promise): promise.success(counter) } } } DispatchQueue.concurrentPerform(iterations: 100_000) { _ in actor.offer(.increment) } let promise = CoPromise<Int>() promise.whenSuccess { print($0) } actor.offer(.getCounter(promise)) actor.close()DeclarationParameterstypeCoChannelgeneric type.bufferTypeThe type of channel buffer. bodyThe closure that will be executed inside coroutine. Return ValueCoChannel.Senderfor sending messages to an actor.
 CoroutineScheduler Protocol Reference
        CoroutineScheduler Protocol Reference