如何在async方法中不使用fixed或GCHandle获取this的指针?
结论:无法实现,且不应尝试
核心原因
在async方法中,await前后的执行线程可能切换,而值类型(结构体)的this的存储位置必然会发生变化——C#的async状态机会将结构体的成员复制到堆上的状态机实例中,以保证异步执行时的状态留存。这意味着await前获取的this指针,在await后必然失效,因为原存储位置可能已被回收或复用。
现有方案的局限性
- 直接取
&this:unsafe代码中不允许对this取地址,因为this并非局部变量,没有隐式固定的语义,且其存储位置本身不稳定。 - 使用
fixed语句:fixed块是同步语义,无法在块内调用await;一旦退出fixed块,指针立即悬空,因为结构体可能被移动或回收。 GCHandle.Alloc(this):会触发结构体的装箱操作,生成堆上的副本,无法指向原结构体实例,不符合你的需求。ref/in参数传递:C#不允许async方法接收ref或in参数;传值方式会直接生成结构体副本,效果和装箱一致。
最终结论
不存在不使用fixed或GCHandle就能在async方法中获取this有效指针的方案。只要涉及await,就必须接受this的存储地址会发生变化的事实——只有通过装箱(GCHandle)或非托管堆分配(手动复制结构体到非托管内存),才能在await后保持指针的有效性,但前者会产生副本,后者需要手动管理内存,均存在额外开销或风险。
内容的提问来源于stack exchange,提问作者Rook
相关产品推荐
相关产品推荐

