1 c# memory-management .net-core
假设我们有一个method A声明变量“int Q”,启动另一个在新线程中method B接受变量Q作为参数并返回。ref int
考虑到,根据这个答案,.NET 将“堆栈中变量 Q 的地址”传递给通过method B引用传递时 - 当控制离开 的范围时method A,运行时不应该清除该方法内分配的变量堆栈吗?这是否意味着如果原始线程继续运行(并在堆栈上分配其他变量),method B可能会损坏这些变量之一,因为它引用的“地址”不再属于变量Q?
我肯定理解这个错误,因为当我运行下面的代码片段时,我没有注意到manyInts数组有任何变化。
public static void Main(string[] args)
{
Outer();
int[] manyInts = new int[100000];
Thread.Sleep(5000);
}
private static void Outer()
{
int crossThreadInt = 10;
try
{
var t = Task.Run(() => AsyncInfiniteMethod(ref crossThreadInt));
t.Wait(2000);
}
catch (Exception)
{
// ignored
}
finally
{
Console.WriteLine(crossThreadInt);
}
}
private static void AsyncInfiniteMethod(ref int number)
{
while (true)
{
Thread.Sleep(100);
number++;
}
}
Run Code Online (Sandbox Code Playgroud)
当您将变量“捕获”到 lambda 委托或异常方法中时:它会更改位置 - 它不再是堆栈变量。本质上,这是:
int crossThreadInt = 10;
// ...
var t = Task.Run(() => AsyncInfiniteMethod(ref crossThreadInt));
Run Code Online (Sandbox Code Playgroud)
变成:
var captureContext = new SomeCompilerGeneratedClass();
captureContext.crossThreadInt = 10;
// ...
var t = Task.Run(captureContext.SomeCompilerGeneratedMethod);
class SomeCompilerGeneratedClass {
public int crossThreadInt;
public void SomeCompilerGeneratedMethod() {
AsyncInfiniteMethod(ref this.crossThreadInt)
}
// etc
}
Run Code Online (Sandbox Code Playgroud)
所以:问题不存在:整数从来都不是堆栈局部变量;它是一个类的一个字段。捕获上下文对象(拥有生命周期)保持活动状态,因为它是委托的“目标”实例。
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |