DispatchQueue总结→任务替换(Swift)

   2023-02-07 学习力0
核心提示:介绍自 Objective-C 时代以来一直支持我们的 DispatchQueue 即将随着 Swift Concurrency (async/await) 的出现而结束其角色。本文展示了如何将 Task 替换为 Task 用于使用 DispatchQueue 的各种用例。笔记基本上你不需要在iOS 13.0+中使用DispatchQueue请让我

介绍

自 Objective-C 时代以来一直支持我们的 DispatchQueue 即将随着 Swift Concurrency (async/await) 的出现而结束其角色。

本文展示了如何将 Task 替换为 Task 用于使用 DispatchQueue 的各种用例。

笔记

  • 基本上你不需要在iOS 13.0+中使用DispatchQueue
    • 请让我知道是否有一个只能用DispatchQueue实现的过程
      • DispatchQueue 的优点是更容易调试,因为你可以命名队列
  • 我没有检查之前/之后的处理是否完全相同

环境

  • 操作系统:macOS 蒙特雷 12.5.1
  • Xcode: 14.0 (14A309)
  • 斯威夫特:5.7

更换清单

DispatchQueueTask 替换列表。

调度队列 任务
DispatchQueue.main.sync(excute:) MainActor.run(resultType:body:)
DispatchQueue.main.async(excute:) Task.detached { @MainActor in ... }
DispatchQueue.async(group:) async let
DispatchQueue.main.asyncAfter(deadline:execute:) iOS 13.0+:Task.sleep(nanoseconds:)
iOS 16.0+:Task.sleep(for:)

我敢肯定还有其他方法可以替换它。这里有一些简单的写作方法。

用例

我将按用例介绍替换。

等待特定过程完成

等待特定过程完成的用例。

直到现在我使用DispatchQueue.main.sync(excute:),但现在我使用MainActor.run(resultType:body:)

在下面的示例中,Before 和 After 都按照 12 的顺序输出。

// Before
DispatchQueue.main.sync {
  print("1")
}
print("2")

// After
Task {
  await MainActor.run {
    print("1")
  }
  print("2")
}

但是DispatchQueue.main.sync(excute:)在主线程执行时会因为死锁而崩溃,所以基本上不应该使用它,所以这个用例的替代品可能不多。

异步执行特定处理

这是一个异步执行特定处理的用例。

到目前为止,我使用的是DispatchQueue.main.async(excute:),但从现在开始,我将使用Task.detached { @MainActor in ... }

这个替换是写在 Swift 提案中的。

在下面的示例中,Before 和 After 都以 21 的顺序输出。

// Before
DispatchQueue.main.async {
  print("1")
}
print("2")

// After
Task.detached { @MainActor in
  print("1")
}
print("2")

如果不需要分离任务,可以写Task { @MainActor in ... }
如果您只是希望闭包中的处理在主线程上运行,我认为最好不要使用 Task.detached

// このように書くことのほうが多い
- Task.detached { @MainActor in
+ Task { @MainActor in
  print("1")
}
print("2")

异步执行多个操作并等待它们完成

异步执行多个操作并等待它们完成的用例。

到目前为止,我使用的是DispatchQueue.async(group:),但现在我使用的是async let
即使没有异步方法返回值,也可以通过显式指定 Voidasync let 将其分配为变量。

// Before
let group = DispatchGroup()
let queue1 = DispatchQueue(label: "com.example.myqueue1")
let queue2 = DispatchQueue(label: "com.example.myqueue2")
let queue3 = DispatchQueue(label: "com.example.myqueue3")

queue1.async(group: group) {
  print("1")
}
queue2.async(group: group) {
  print("2")
}
queue3.async(group: group) {
  print("3")
}

group.notify(queue: .main) {
  print("4")
}

// After
async let queue1: Void = printAsync("1")
async let queue2: Void = printAsync("2")
async let queue3: Void = printAsync("3")

_ = await (queue1, queue2, queue3)

print("4")

private func printAsync(_ text: String) async {
  print(text)
}

延迟执行特定处理

这是一个延迟执行特定处理的用例。

到目前为止,我使用DispatchQueue.main.asyncAfter(deadline:execute:) 并将其作为闭包运行。
从现在开始,我们使用await Task.sleep(nanoseconds:) 来表示通过休眠来延迟执行。

但是,要指定的单位是纳秒,使用起来有点困难。
在 Xcode 14.1 (Swift 5.7.1) 和 iOS 16.0+ 中,您可以使用 Task.sleep(for:) 指定单位,因此最好使用它。

// Before
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
  // ...
}

// After
Task {
  // iOS 13.0+
  try await Task.sleep(nanoseconds: 100_000_000)

  // iOS 16.0+
  try await Task.sleep(for: .nanoseconds(100_000_000))
  try await Task.sleep(for: .microseconds(100_000))
  try await Task.sleep(for: .milliseconds(100))
  try await Task.sleep(for: .seconds(0.1))
  // ...
}

综上所述

这将DispatchQueue 替换为Task 并且更智能DispatchQueue→Task置き換えまとめ(Swift)

还有其他使用DispatchQueue 的用例,所以如果我得到评论,我想添加它们。

参考链接


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308627623.html

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
    PHP 使用 Swoole - TaskWorker 实现异步操作 My
    在一般的 Server 程序中都会有一些耗时的任务,比如:发送邮件、聊天服务器发送广播等。如果我们采用同步阻塞的防水去执行这些任务,那么这肯定会非常的慢。Swoole 的 TaskWorker 进程池可以用来执行一些异步的任务,而且不会影响接下来的任务,很适合处理以
    02-09
  • 教程一:用ASP.NET MVC创建一个TaskList应用程序
    教程一:用ASP.NET MVC创建一个TaskList应用程
    原文地址:http://www.asp.net/learn/mvc/tutorial-01-cs.aspx本篇教程目的是让你了解创建一个ASP.NET程序是“怎么样子的”。在这篇教程里,我会从头到尾快速地创建一整个ASP.NETMVC程序。我会告诉你如何创建一个简单的TaskList程序。如果你跟ASP或者APS.NET
    02-09
  • Delphi并行库System.Threading 之ITask 1
    不知什么时候,也许是XE8,也许是XE8之前 .Delphi里面多了个System.Threading的并行库.虽然己经有非常棒的第三方并行库QWorker,但我还是更喜欢官方的东西.下面是一段使用System.Threading中ITask的代码procedure TForm3.SpeedButton1Click(Sender: TObject);var
    02-09
  • 【C#】【笔记】Task.Factory.StartNew的相关异
    3、Task.Factory.StartNew 将来的任务执行有可能劫持现有任务并杀死其进程.。a、推荐方法    引入System.Collections.Concurrent 命名空间–线程安全数据结构    把非线程安全的数据结构替换成下面的数据结构即可    BlockingCollectionT 为实现
    02-09
  • C#使用Task实现并行编程 crush什么意思
    故事背景透着纱的窗外的阳光, 又是一个星期一.慢慢来一看时间, 还早, 那么蹦跶起来穿衣刷牙洗脸用代码来说的话, 应该是这样:// Program.csusing System;using System.Diagnostics;using System.Threading;namespace ConsoleApp1{class Program{static void Ma
  • 解决ASP.NET Core在Task中使用IServiceProvider的问题
    解决ASP.NET Core在Task中使用IServiceProvider
    前言    问题的起因是在帮同事解决遇到的一个问题,他的本意是在EF Core中为了解决避免多个线程使用同一个DbContext实例的问题。但是由于对Microsoft.Extensions.DependencyInjection体系的深度不是很了解,结果遇到了新的问题,当时整得我也有点蒙了,所
    02-08
  • [ Laravel 5.3 文档 ] 官方包 —— Envoy Task
    1、简介Laravel Envoy为运行在远程主机上的通用任务定义提供了一套干净的、最简化的语法。使用Blade风格语法,你可以轻松为开发设置任务,Artisan命令,以及更多,目前,Envoy只支持 Mac 和 Linux 操作系统。安装首先,使用 Composer 的global命令安装 Envoy
  • swoole-task:基于 PHP swoole 扩展开发的异步
    swoole-taskswoole-task是基于PHP swoole扩展开发的一个异步多进程任务处理框架,服务端和客户端通过http协议进行交互。它适用于任务需要花费较长时间处理,而客户端不必关注任务执行结果的场景.比如数据清洗统计类的工作,报表生成类任务。环境要求PHP 5.4
  • cmd Tasklist与Tskill管理Windows系统进程
    相信大家都有用命令行(CMD)解决问题的习惯,起码我感觉自己在处理Windows系统故障时越来越离不开Windows PE了,今天我想介绍两个很实用的命令:Tasklist与Tskill。
  • win2003下杀任何进程的命令(taskkill,ntsd)
    才能关掉一个用任务管理器关不了的进程?大多数人想到的都是专门工具,如IceSword。其实用Windows自带的工具就能杀大部分进程
    11-06 taskkillntsd
点击排行