.NET 4.5中异步任务未完成会产生什么影响?

6
假设你有一个 Web 处理程序,调用了一个异步方法,代码如下:
var foo = await SomeMethod();

由于糟糕的编码(没有CancellationToken、没有超时等),SomeMethod永远无法完成。用户感到沮丧,于是在浏览器上按下“停止”按钮,然后去了酒吧。

假设这种情况发生在许多用户身上。

我知道我可以编写一个超时来防止它永远等待,但如果我不做呢......会发生什么?这是内存泄漏吗?它最终会被清理掉吗?最坏的情况是什么?


当然最好避免使用永久的await,但是坏事可能会发生,你必须实现某种超时策略 - Ilya Tereschuk
2个回答

4

而 SomeMethod 从不返回。用户取消请求并去酒吧。

这完全不一样。

如果 SomeMethod 永远不会完成,则存在内存泄漏。您永远不应编写此类代码。

另一方面,如果用户取消请求(取消 CancellationToken),则该方法将会完成,可能会出现 OperationCanceledException


我的措辞不够好。应该写成“SomeMethod永远不会返回。因此,用户按下浏览器上的“停止”按钮并前往酒吧。”我假设没有CancellationToken,我只想知道当被放弃的任务堆积时会发生什么。了解可能会失败的情况以及如何失败将有助于我在现场检测出这个问题。 - roufamatic
当然,任务应该被编写完成!但感谢那篇文章,非常棒的阅读材料。 - roufamatic
@roufamatic:好的,所以你在问的是被放弃的任务,而不是未完成的任务。在这种情况下,它们会自然地运行到完成(除非应用程序被卸载)。 - Stephen Cleary
非常抱歉展示了糟糕的沟通技巧。我确实是指未完成的任务。我的先前评论应该是指“是的,它们应该被编写为完成,但假设在这种情况下它们没有被完成?” 假设的情况是由于一个不完整的任务而导致用户放弃了网页请求。从诊断角度来看,会是什么样子?听起来像是内存泄漏。 - roufamatic
如果任务确实从未完成,则只会看到内存/资源泄漏。 - Stephen Cleary

2

这取决于由SomeMethod返回的任务的实现方式。任务负责调用后续操作(ContinueWith),从而推进执行。如果任务没有继续执行,就会导致内存泄漏。大多数异步API提供了超时机制来防止出现这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接