c# - 为什么在不安全的部分禁止等待?

标签 c# unsafe async-await

根据 http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspxawait 关键字在 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/

相关文章:

c# - 如何将 C# 流式传输视频(图像)到 HTML5 客户端?

java - 使用Arraylist复制三维数组不安全?

python - 如何让 python wait for "nothing",首先运行事件循环

c# - Settings.settings 中是否允许可空的 int 类型?

c# - c#中相同值的多个访问器

java - 从未通过 allocateInstance(Java) 从对象调用 Finalize

rust - `unsafe` 函数的最佳实践是什么,其中只有一小部分代码实际上在做 `unsafe` 的事情?

c# - RavenDb LoadAsync 不返回也不抛出异常

javascript - 异步/等待返回结果不 promise

c# - 从 ObjectID 列表中查找所有 MongoDB 文档