如何为等待函数调用添加超时

2023-12-03

向等待函数添加超时的最佳方法是什么?

Example:

/// lets pretend this is in a library that I'm using and I can't mess with the guts of this thing
func fetchSomething() async -> Thing? {
    // fetches something
}

// if fetchSomething() never returns then doSomethingElse() is never ran. Is there anyway to add a timeout to this system?
let thing = await fetchSomething()
doSomethingElse()

我想让系统在 fetchSomething() 永远不会返回的情况下更加健壮。如果这是使用组合,我会使用超时运算符。


一个人可以创建一个Task, 进而cancel如果它在一定时间内没有完成。例如,并行启动两个任务:

// cancel the fetch after 2 seconds

func fetchThingWithTimeout() async throws -> Thing {
    let fetchTask = Task {
        try await self.fetchThing()                           // start fetch
    }

    let timeoutTask = Task {
        try await Task.sleep(for: .seconds(2))                // timeout in 2 seconds
        fetchTask.cancel()
    }

    return try await withTaskCancellationHandler {            // handle cancelation by caller of `fetchThingWithTimeout`
        let result = try await fetchTask.value
        timeoutTask.cancel()

        return result
    } onCancel: {
        fetchTask.cancel()
        timeoutTask.cancel()
    }
}

// here is a random mockup that will take between 1 and 3 seconds to finish

func fetchThing() async throws -> Thing {
    let duration: TimeInterval = .random(in: 1...3)
    try await Task.sleep(for: .seconds(duration))
    return Thing()
}

If the fetchTask首先完成,它将到达timeoutTask.cancel并停止它。如果timeoutTask首先完成,它将取消fetchTask.

显然,这取决于《公约》的实施fetchThing功能。它不仅应该检测取消,还应该抛出错误(可能是CancellationError)如果被取消。如果没有有关实施的细节,我们无法进一步发表评论fetchTask.

例如,在上面的例子中,而不是返回一个可选的Thing?,我会返回Thing,但是拥有它throw如果被取消,则会出现错误。


注意withTaskCancellationHandler是必需的,因为我们使用了非结构化并发,其中取消不会自动为我们传播。我们必须手动处理这个问题。或者,您可以使用任务组保持结构化并发:

func fetchThingWithTimeout() async throws -> Thing {
    try await withThrowingTaskGroup(of: Thing.self) { group in
        group.addTask {
            try await self.fetchThing()                       // start fetch
        }

        group.addTask {
            try await Task.sleep(for: .seconds(2))            // timeout in 2 seconds
            throw CancellationError()
        }

        guard let value = try await group.next() else {       // see if fetch succeeded …
            throw FetchError.noData                           // theoretically, it should not be possible to get here (as we either return a value or throw an error), but just in case
        }

        group.cancelAll()                                     // … but if we successfully fetched a value, cancel the timeout task, and
        return value                                          // … return value
    }
}

我犹豫是否要提及这一点,但尽管上面假设fetchThing表现良好(即可取消),即使不运行,模式上也有一些排列可以工作(即运行doSomethingElse在一些合理的时间表中,即使fetchThing“永远不会回来”)。

但这本质上是一种不稳定的情况,因为所使用的资源fetchThing在完成之前无法恢复。 Swift 不提供抢先取消,因此虽然我们可以轻松解决确保doSomethingElse最终运行,如果fetchThing可能永远不会在合理的时间表内完成,你还有更深层次的问题。

你真的应该找到一个演绎something如果尚未取消,则可以取消。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为等待函数调用添加超时 的相关文章

  • 在 SwiftUI 中,如何执行手势但将手势转发到其后面的视图?

    我正在创建一个工具提示系统 如果用户触摸工具提示之外的任何地方 我想关闭工具提示 我希望这样在工具提示之外的触摸既可以消除工具提示 又可以激活用户点击的任何控件 因此 您可以打开一个工具提示 然后仍然单击工具提示外部的按钮 并在第一次点击时
  • SwiftUI - 从 NSObject 继承的 ObservableObject 在 iOS 13 中不会更新

    我知道 这是 无法在 iOS XX 中工作 问题之一 但我完全陷入困境 所以我有一个ObservableObject继承自的类NSObject 因为我需要听委托方法UISearchResultsUpdating class SearchBa
  • 弱变量中间为零

    弱变量什么时候变为零 weak var backgroundNode SKSpriteNode texture SKTexture image initialBackgroundImage backgroundNode position C
  • 从同步上下文调用异步方法

    我在代码中通过 HTTP 调用服务 最终使用 HttpClient SendAsync 方法 然后从 WebAPI 控制器操作调用此代码 大多数情况下 它工作得很好 测试通过 但是当我在 IIS 上部署时 我遇到了死锁 因为异步方法调用的调
  • 在 Swift 中使用 commitEditingStyle 动态删除 UITable 部分

    我正在处理一个无法解决的问题 我有一个来自客户数据库数组的名称表 每个客户在其他数据成员中都有一个名称属性 我可以成功删除某个部分中的行 但我不能删除该部分 当该部分中的最后一行被删除时 该部分必须消失 I got NSInternalIn
  • 从 Firestore 获取值并使用异步将输出存储为全局

    我正在尝试获取 firestore 数据 然后将其存储在变量中 async function getchildContent Parent Message let count 0 var db firebase firestore var
  • 可能的 std::async 实现错误 Windows

    看来 std async 的 Windows 实现存在错误 在重负载下 大约每秒启动 1000 个异步线程 异步任务永远不会被调度 并且等待返回的 future 会导致死锁 请参阅这段代码 使用延迟启动策略而不是异步进行修改 Bundlin
  • 仅在 iPhone X 上显示状态栏

    如果不是 iPhone X 则希望隐藏状态栏 如果是 iPhone X 则希望显示状态栏 这很可能必须以编程方式完成 因为 plist 中没有支持此功能的键 我发现的最接近的一个是UIStatusBarHidden 方法一 You have
  • 断点会停止所有线程吗?

    如果我的程序中有两个线程同时运行 并在其中一个线程上设置了断点 那么当遇到此断点时 另一个线程也会停止 还是会继续执行 我用 Java 编写并使用 NetBeans 断点可以选择它们的行为方式 挂起单个线程或所有线程
  • 快速钥匙串更新只有在第二次尝试时才起作用

    您好 我在更新存储在钥匙串中的登录信息方面遇到了 iOS 钥匙串的一个非常奇怪的问题 因此 如果没有保存的凭据 则正确运行保存函数会保存登录信息 如果登录信息已存在并且用户更新了密码 则更新功能仅正确更新密码 但是 如果登录信息存在并且我尝
  • 为什么等待冷任务不会抛出

    我只是在尝试看看当一个冷任务 即一个任务 时会发生什么Task尚未开始 正在等待 令我惊讶的是 代码永远挂起并且 完成的 永远不会被打印 我希望抛出异常 public async Task Test1 var task new Task g
  • 是否可以更改枚举中的关联值?

    我正在使用 Swift 枚举 想知道是否有一种方法可以更改枚举的关联值 例如下面的代码尝试但失败了 enum myEnum case SomeCase Int mutating func someFunc switch self case
  • iOS Swift 在后台下载大量小文件

    在我的应用程序中 我需要下载具有以下要求的文件 下载大量 例如 3000 个 小 PNG 文件 例如 5KB 逐个 如果应用程序在后台继续下载 如果图像下载失败 通常是因为互联网连接丢失 请等待 X 秒然后重试 如果失败Y次 则认为下载失败
  • 如何将CIFilter应用到UIView上?

    根据Apple docs 过滤属性CALayer不支持iOS 当我使用正在申请的应用程序之一时CIFilter to UIView即 Splice Funimate 和 Artisto 的视频编辑器 Videoshow FX 这意味着我们可
  • 循环多个 UIAlertController

    在某些情况下 我的应用程序需要显示多个警报消息 错误消息在启动时收集 并且需要一次向用户显示一条 当第一个被确认后 应该呈现下一个 问题在于 显然 它们都试图同时执行 有没有一种聪明的方法可以同步执行此操作 这是一些简单描述我想要做的事情的
  • 在 Swift 中以编程方式为 iOS 制作带有名字首字母的图像,例如 Gmail

    我需要在 UITableView 中显示与其姓名相对应的每个用户的个人资料图片 在下载图像之前 我需要显示一张带有他名字的第一个字母的图像 就像在 GMail 应用程序中一样 如何在 Swift for iOS 中以编程方式执行此操作 不需
  • iOS Swift 和 reloadRowsAtIndexPaths 编译错误

    我与 xCode Swift 陷入僵局并刷新 UITableView 的单行 这条线有效 self tableView reloadData 而这条线没有 self tableView reloadRowsAtIndexPaths curr
  • 在 UITableView 的部分标题文本下方添加一些边距

    我已经设计了标题文本的样式 func tableView tableView UITableView cellForRowAtIndexPath indexPath NSIndexPath gt UITableViewCell let ce
  • 领域:结果 和列表

    是否可以转换Results
  • 如何将自定义 C 代码放入 SwiftPM 包中?

    我正在尝试将 C 代码打包到 Swift 模块中 我们称之为CModule 一旦我将其放入项目的基本文件夹中 Swift模块 并配置了搜索路径 我可以在 Swift 文件中自动完成工作 并检测错误 警告 问题是 导入时它无法识别该模块 并且

随机推荐

  • 如何将 UITextview 样式设置为圆角矩形文本字段?

    我正在使用文本视图作为评论编辑器 在属性检查器中 我找不到类似边框样式属性的任何内容 以便我可以使用圆角矩形 例如UITextField 所以 问题是 我该如何设计UITextView like a UITextField带有圆角矩形 没有
  • 设置 Maven 插件连接器错误

    我正在尝试将项目导入 Spring Source Tool Suite 最新版本 该项目之前是从 Maven 原型目录创建的 我收到屏幕截图中显示的错误 我能够在不同的机器上导入相同的项目 但使用相同的 Maven 存储库 我复制了整个 m
  • 1:1 或 1:0 关系的标准化

    当使用关系数据库并且您想要 3NF 您用英语称之为 3NF 吗 时 您可以将 1 1 关系拉到一张表中 但如果配给比例是 1 0 1 意思是 或 会发生什么呢 然后将它们分开以避免表格中出现空格 在这种情况下 将它们分开是有效的 3NF 吗
  • Java DOM 通过 ID 获取元素

    我正在 Java 中使用 DOM 解析器将子节点添加到现有节点中 我的 XML 是
  • 如何查找 SQL Server Management Studio 的服务器名称

    我安装了 Microsoft SQL Server 2008 当我启动 SQL Server Management Studio SSMS 时 我得到Connect to Server带有空白文本框的登录窗口Server name 我尝试了
  • 在 mysql 8 中使用 GROUP BY

    我已经升级了 MySQL 服务器 现在我遇到了 group by 问题 select from tickets WHERE status 0 group by tnumber ORDER BY created at DESC 错误是 SEL
  • mllib NaiveBayes 中的类数量有限制吗?调用 model.save() 时出错

    我正在尝试训练一个模型来预测文本输入数据的类别 我使用以下方法遇到了似乎数值不稳定的问题pyspark ml classification NaiveBayes当类别数量超过一定数量时 对词袋进行分类 在我的现实世界项目中 我有大约 10
  • Javascript for 循环和警报

    我正在循环浏览链接列表 我可以正确获取标题属性 并希望它在单击时显示 当页面加载并单击链接时 所有链接标题都会一一提醒 我究竟做错了什么 function prepareShowElement var nav document getEle
  • 仅在 apex 报告的某些行上显示“编辑”链接

    我有以下报告结构 显示全年产品的销售目标和销售额 每个产品都有两行 一行显示销售额 一行显示 sales target 目前 我的报告在报告的每一行旁边都有一个编辑链接 有没有办法从 sales target 行中删除编辑链接 select
  • 无法使用 PRAW 从某些 Reddit 子版块中获取随机帖子

    我正在尝试使用此代码让一个不和谐的机器人从reddit发送图像 只是为了抓取而不是发送 def random post subreddit while True post reddit subreddit subreddit random
  • Android:如何获取自定义View的高度和宽度? [复制]

    这个问题在这里已经有答案了 我该如何使用getMeasuredWidth and getMeasuredHeight 它总是返回 0 这和有什么区别getHeight and getWidth 刚刚找到了获取自定义视图的高度和宽度的解决方案
  • SQLite中保存资源路径

    我需要将图像保存在 SQLite 数据库的资源文件夹中 该数据库是预加载的 复制到数据 路径 因此在运行时不会填充 我尝试将其保存在 SQLite 的文本字段中 R drawable picture1 我的drawable文件夹中有大约30
  • MySQL FULLTEXT 不适用于多个字段

    我有一个标准的 MySQL 全文查询 如下所示 SELECT FROM accounts WHERE MATCH first name username AGAINST stringhere 问题是 它找不到该字段的全文索引first na
  • 通过 jQuery 添加 JSF 标签/组件

    这是我所做的 var a document getElementById panelForm tableId01
  • NSIS 系统 kernel32::LoadLibrary 不搜索 Outdir 或 Path

    我正在尝试在 NSIS 安装程序中加载并调用 C 库 DLL 的函数 当我尝试加载 DLL 时 发出错误 126 ERROR MOD NOT FOUND 这是我用来测试的最小安装程序脚本 OutFile Main exe ShowInstD
  • 如何配置Json.NET自定义序列化?

    由于我无法控制的原因 我从外部服务返回的数据被格式化为字符串数组的数组 string one string two 我试图将其反序列化为具有两个属性的对象 public class MyObject public string Proper
  • ajax 调用导致错误而不是成功

    在我的 ASP net mvc3 项目中 我使用 ajax 调用将 json 数据发送到控制器公司中的创建操作方法 但是当我调试ajax调用时 它总是以错误结果而不是成功结果结束 阿贾克斯调用 ajax url Company Create
  • 在javascript中移动对象元素位置

    我正在尝试找到一种将对象元素移动到特定位置的方法 例如 我有这个对象 element1 object element2 element3 我搜索将 element3 移动到第一个位置 element3 element1 element2 感
  • 从 PDO 准备好的语句中获取原始 SQL 查询字符串

    在准备好的语句上调用 PDOStatement execute 时 有没有办法让原始 SQL 字符串执行 出于调试目的 这将非常有用 我假设您的意思是您想要最终的 SQL 查询 并将参数值插入其中 我知道这对于调试很有用 但这不是准备好的语
  • 如何为等待函数调用添加超时

    向等待函数添加超时的最佳方法是什么 Example lets pretend this is in a library that I m using and I can t mess with the guts of this thing