根据http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx,await
块中禁止使用unsafe
关键字,仅提及“保留非托管指针所固有的困难”。对这些困难有什么好的解释吗?
答案 0 :(得分:8)
您需要了解的两件基本事项。异步方法被C#编译器重写为一个小类,其中包含一个包装状态机的无法形容的名称。 async方法的局部变量成为该类的字段。
不安全的代码通常依赖于能够创建指向局部变量的指针。 fixed 语句就是这样,它创建了一个隐藏的局部变量,垃圾收集器可以看到它,从而在发生垃圾收集时更新,从而移动正在修复的数组。创建指向局部变量的指针很好,这些变量不会被垃圾收集器移动。线程堆栈始终位于虚拟内存地址空间中的固定位置。
连接这两个,你看到问题,一个局部变量可以变成一个类的字段,一个字段在发生垃圾收集时发生变化。突然把不安全的代码变成破坏代码。
演示此问题的代码段:
class Example {
int field;
unsafe void Method() {
int local = 42;
int* p = &local; // fine
int* q = &field; // CS0212
}
}
C#团队可以努力仔细分析重写后不安全代码仍然可以的情况。但是有些情况只是不可修复,比如 fixed 语句。一堆工作只给程序员带来令人失望的消息,通常是因为一个令人困惑的原因。这里理智的做法是简单地宣布不安全的代码不受限制。