【问题标题】:How does Dart:io clean up Futures that timeout?Dart:io 如何清理超时的期货?
【发布时间】:2016-08-01 22:36:36
【问题描述】:

假设我们使用配置了超时的 http 包从 dart:io 应用程序发出 HTTP 请求:

dynamic getSomething(String url) async {
  try {
    var response = await http.get(url).timeout(new Duration(seconds: 30));
    return JSON.decode(response.body);
  } catch (_) {
    return null;
  }
}

这里有两个future,一个由http.get(请求Future)生成,另一个由Future.timeout(超时Future)生成。如果请求 Future 完成, 它的值被传递到超时 Future ,这反过来又完成了。这很好。

但是,如果 http.get 未在 30 秒内完成,则超时未来将完成并抛出 TimeoutException。请求 Future 会发生什么? 当然,与请求 Future 相关的一些状态和内存分配并没有通过运行超时 Future 来专门清理。更糟糕的是, 如果请求 Future 在超时后完成,该代码仍将执行。超时Future是否有责任专门取消请求- 在这种情况下,这是不可能的,因为它被埋在包中 - 或者是否有其他必须使用的机制?

更一般地说,永远不会完成的 Future 最终会清理其状态和内存,还是永远挂起?

【问题讨论】:

标签: asynchronous dart timeout async-await future


【解决方案1】:

当没有对它的引用时,Future 将被垃圾收集,就像任何其他变量一样。 Future 变量在本质上没有什么不同。例如,它们不是操作系统构造。

在您的 http 示例中,超时 Future 与原始 Future 链接在一起,因此如果原始 Future 完成,那么超时 Future 也将完成。在相反的情况下,超时触发,http 操作将持有对原始未来的引用(它持有对超时未来的引用),直到 http 操作完成。因此,Futures 可能泄漏的唯一方法是,如果 http 请求从未返回,但此时您正在泄漏 http 连接,并且您会遇到比泄漏几个 Futures 更大的问题。

请注意,Future 超时完成并不意味着存在错误。错误的行为不同。错误会导致 Future 调用 catchError() 或调用您的回调。

【讨论】:

    猜你喜欢
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多