【问题标题】:How can I cancel/abort a zone in Dart?如何取消/中止 Dart 中的区域?
【发布时间】:2018-07-09 19:19:41
【问题描述】:

我有一个 http web 服务器,我正在尝试检测长时间运行的请求并中止它们。以下代码在超时后成功返回客户端,但异步区域仍继续运行完成。 我如何才能真正杀死请求处理程序?

var zone = runZoned(() {
  var timer = new Timer(new Duration(seconds: Config.longRequestTimeoutSeconds), () {
    if (!completer.isCompleted) { // -- not already completed
      log.severe('request timed out');
      // TODO: This successfully responds to the client early, but it does nothing to abort the zone/handler that is already running.
      //       Even though the client will never see the result (and won't have to wait for it), the zone/handler will continue to run to completion as normal.
      // TODO: Find a way to kill/abort/cancel the zone
      completer.complete(new shelf.Response(HttpStatus.SERVICE_UNAVAILABLE, body: 'The server timed out while processing the request'));
    }
  });

  return innerHandler(request) // -- handle request as normal (this may consist of several async futures within)
    .then((shelf.Response response) {
      timer.cancel(); // -- prevent the timeout intercept
      if (!completer.isCompleted) { // -- not already completed (not timed out)
        completer.complete(response);
      }
    })
    .catchError(completer.completeError);
});

【问题讨论】:

    标签: asynchronous dart future zone dart-shelf


    【解决方案1】:

    除了它自己,没有什么能杀死正在运行的代码。如果您希望代码可中断,则需要某种方式来告诉它,并且代码本身需要终止(可能通过抛出错误)。在这种情况下,innerHandler 需要能够在请求时自行中断。如果不是你的代码,那可能是不可能的。

    可以编写一个区域,在设置标志时停止异步事件的执行(通过修改 Zone.run 等),但您必须非常小心 - 它可能永远不会到达如果您开始丢弃异步事件,则异步 finally 会阻塞并释放资源。因此,不建议将其作为通用解决方案,仅适用于愿意进行手动资源管理的非常细心的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-28
      • 2017-02-01
      • 2013-01-17
      • 2020-01-24
      • 2020-07-21
      • 2013-06-05
      • 2016-08-12
      相关资源
      最近更新 更多