根据 http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx ,await
关键字在 unsafe
block 内被禁止,仅提及“保留非托管指针所固有的困难”。对于这些困难是什么,是否有一个很好的解释?
最佳答案
您需要了解的两件基本事情。异步方法被 C# 编译器重写为一个小类,其名称难以形容,它包装了一个状态机。异步方法的局部变量成为该类的字段。
不安全代码通常依赖于能够创建指向局部变量的指针。 fixed 语句就是这样,它创建了一个隐藏的局部变量,垃圾收集器可以看到该变量,因此当垃圾收集发生时移动正在修复的数组时更新。创建指向局部变量的指针很好,这些变量不会被垃圾收集器移动。线程的堆栈总是在虚拟内存地址空间中的固定位置。
将两者联系起来,您就会看到问题所在,一个局部变量可以变成一个类的字段,一个在垃圾回收发生时其地址确实改变的字段。突然将不安全代码变成破坏代码。
演示问题的代码片段:
class Example {
int field;
unsafe void Method() {
int local = 42;
int* p = &local; // fine
int* q = &field; // CS0212
}
}
C# 团队本可以努力仔分割析重写后不安全代码仍然正常的情况。但有些情况是无法修复的,例如 fixed 语句。一堆工作只会给程序员带来令人失望的消息,通常是出于令人困惑的原因。明智的做法是简单地声明不安全代码不受限制。
关于c# - 为什么在不安全的部分禁止等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15182188/