WWDC21-Concurrency-Structured

1. 前言

  • 闭包形式的异步代码并不是structured
  • 调用async函数并不会创建一个task,task只能通过显式声明来创建

2. Async-let Tasks

  • try-await取值方式,会阻塞当前线程。当取值完成之后才会赋值给变量并恢复线程

    • let (data, response) = try await URLSession.shared.data(for: request)
      <!--0-->
  • Async-let相当于把操作交给子任务去处理

    • 只有所有的子任务都处理玩了,父任务才算处理完成
    • 若一个任务有两个子任务,其中一个子任务抛出了一个error,这时父任务会把另外那个子任务标记为cancellation,表示他的结果已经不需要了,这个子任务会自己在恰当的时机终止运行。
  • cancellation checking

    • 若一个任务有多个子任务,需要对子任务是否被取消进行检查

    • func fetchThumbnails(for ids: [String]) async throws -> [String: UIImage] {
          var thumbnails: [String: UIImage] = [:]
          for id in ids {
              try Task.checkCancellation() // 检查当前任务是否被取消
              thumbnails[id] = try await fetchOneThumbnail(withID: id)
          }
          return thumbnails
      }
      <!--1-->
  • group中的操作会并行无序执行

  • @Sendable:生成task的闭包。sendable闭包不能捕获mutable变量。只能捕获值类型、actors、实现了synchronization的类

4. Unstructured Tasks

  • 会中断UnstructuredTask所在的task,仍然继承父task的优先级、actors、变量。但是需要手动管理

  • 在非async函数中调用async函数: async { }

    • func collectionView(_ view: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt item: IndexPath) {
          let ids = getThumbnailIDs(for: item)
          thumbnailTasks[item] = async { // 新建一个task
              defer { thumbnailTasks[item] = nil }
              let thumbnails = await fetchThumbnails(for: ids)
              display(thumbnails, in: cell)
          }
      }
      <!--2-->
      

6. AllTasks

Concurrency-Structured-TaskTypes

0%