【发布时间】:2016-11-03 16:44:16
【问题描述】:
我想知道async/await 与垃圾收集局部变量有关的行为。在下面的示例中,我分配了相当大的内存部分并进入了显着延迟。从代码中可以看出,Buffer 在await 之后没有使用。它会在等待时被垃圾收集,还是在函数执行期间内存被占用?
/// <summary>
/// How does async/await behave in relation to managed memory?
/// </summary>
public async Task<bool> AllocateMemoryAndWaitForAWhile() {
// Allocate a sizable amount of memory.
var Buffer = new byte[32 * 1024 * 1024];
// Show the length of the buffer (to avoid optimization removal).
System.Console.WriteLine(Buffer.Length);
// Await one minute for no apparent reason.
await Task.Delay(60000);
// Did 'Buffer' get freed by the garabage collector while waiting?
return true;
}
【问题讨论】:
-
这取决于编译器如何翻译它。 async-await 不是 CLR 概念。 (不过,这是一个有效的问题)。
-
很好的例子,错误的答案如何获得最多的支持。
-
@Soonts:您认为我的回答不正确,我感到有些好笑。我向您保证,这是对 C# 语言做出的保证 的正确陈述。其他任何内容都是可能随时更改的实现细节。
-
@EricLippert,OP 的问题不是理论上的。他不是在问“C# 语言能保证什么”。他宁愿问“它是如何工作的”。当然,实现细节可能会随着下一个 Visual Studio 甚至是服务包而改变。在这种情况下,正确答案将从“否”变为“是”。然而在此之前,在 Visual Studio 2012 的当前生产版本中,正确答案不是“也许”,而是“否”。
-
@soonts async void m(){ var x = new X();等待 n(x.h); } h 是一个句柄, ~X() 释放它。我问你析构函数是否可以在任务完成之前运行。如果是这样,则该过程会破坏数据库。你的回答仍然是因为终结器无法运行,所以这是完全安全的吗?现在你明白为什么重要的是要考虑什么是有保证的,什么是有效的吗?使用良好的工程实践,不要依赖实施细节。
标签: c# .net garbage-collection async-await