如何在 Dart 中 cancel/abort 一个区域?
How can I cancel/abort a zone in Dart?
我有一个 http 网络服务器,我正在尝试检测长 运行 请求并中止它们。以下代码在超时时成功 returns 到客户端,但异步区域仍继续 运行 完成。 我怎样才能真正杀死请求处理程序?
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);
});
除了它本身,没有什么可以杀死 运行 代码。如果您希望代码是可中断的,您需要某种方式来告诉它,并且代码本身需要终止(可能通过抛出错误)。在这种情况下,innerHandler
需要能够在请求时自行中断。如果不是您的代码,那可能是不可能的。
您可以编写一个区域,在设置标志时停止执行异步事件(通过修改Zone.run
等),但您必须非常小心那 - 如果您开始丢弃异步事件,它可能永远不会进入异步 finally 块并释放资源。因此,不建议将其作为通用解决方案,仅适用于愿意进行手动资源管理的非常细心的人。
我有一个 http 网络服务器,我正在尝试检测长 运行 请求并中止它们。以下代码在超时时成功 returns 到客户端,但异步区域仍继续 运行 完成。 我怎样才能真正杀死请求处理程序?
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);
});
除了它本身,没有什么可以杀死 运行 代码。如果您希望代码是可中断的,您需要某种方式来告诉它,并且代码本身需要终止(可能通过抛出错误)。在这种情况下,innerHandler
需要能够在请求时自行中断。如果不是您的代码,那可能是不可能的。
您可以编写一个区域,在设置标志时停止执行异步事件(通过修改Zone.run
等),但您必须非常小心那 - 如果您开始丢弃异步事件,它可能永远不会进入异步 finally 块并释放资源。因此,不建议将其作为通用解决方案,仅适用于愿意进行手动资源管理的非常细心的人。