首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Swift中使用新的并发性将同步函数转换为异步

在Swift中使用新的并发性将同步函数转换为异步
EN

Stack Overflow用户
提问于 2021-11-07 15:44:34
回答 1查看 1.2K关注 0票数 1

我想将同步函数转换为异步函数,但我不知道正确的方法是什么。

假设我有一个同步函数,需要很长时间才能获得数据:

代码语言:javascript
复制
func syncLongTimeFunction() throws -> Data { Data() }

然后我在下面的函数中调用它,它仍然是一个同步函数。

代码语言:javascript
复制
func syncGetData() throws -> Data {
    return try syncLongTimeFunction()
}

但是现在我想把它转换成异步函数。以下是正确的方法:

  • First way:

函数asyncGetData()异步抛出->数据{返回syncLongTimeFunction() }

  • 第二条路:

func asyncGetData2()异步抛出->数据{返回尝试等待DispatchQueue.global().async { do { let data = try self.syncLongTimeFunction() continuation.resume(返回: data) } catch {continuation.resume(抛出:错误)} }

我觉得第一条路就够了,就像罗伯下面有答案一样。但是,当我像下面这样调用主线程上的异步函数时,syncLongTimeFunction()也是在主线程上处理的。所以它会阻塞主线程。

代码语言:javascript
复制
 async {       
     let data = try? await asyncGetData()
 }
EN

回答 1

Stack Overflow用户

发布于 2022-11-26 07:01:57

几点意见:

  1. I将避免引入GCD,因为它不参与协作线程池,Swift并发将无法对系统资源进行推理,避免线程爆炸等

  1. 避免阻塞当前参与者(可能是主要参与者)的简单解决方案是使用一个分离的任务:

func asyncGetData()异步抛出->数据{尝试等待Task.detached { try self.syncLongTimeFunction() }.value }

,它提供了一个异步实现,该实现将在当前参与者.上运行与该任务关联的任务。

  1. 如果构建Data的缓慢过程超出了您的控制范围,那么上面的操作就像您可以做的一样好。但是,如果syncLongTimeFunction是您自己的函数,其中包含一个循环,则可以使用checkCancellation或手动isCancelled测试添加取消支持,例如:

代码语言:javascript
复制
- In `syncLongTimeFunction`, insert a `try Task.checkCancellation()`; and
- In `asyncGetData`, handle cancelation with [`withTaskCancellationHandler`](https://developer.apple.com/documentation/swift/withtaskcancellationhandler(operation:oncancel:%29).

例如:

asyncGetData()异步抛出->数据{ let任务= Task.detached { try self.syncLongTimeFunction() }返回尝试等待withTaskCancellationHandler { try task.value } onCancel:{ task.cancel() } func syncLongTimeFunction()抛出->数据{.对于i in .{尝试Task.checkCancellation() .}返回.}

希望这说明了这个想法。不幸的是,如果没有更多关于syncLongTimeFunction的信息,就不可能变得更加具体。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69873970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档