我修复了我的Vsync库(以前被称为Isis2)中的一个bug,它集中在我和Mono之间在using子句的语义上的分歧。在Vsync中,我有提升线程优先级的锁包装器,以避免优先级反转(高优先级线程可能正在等待低优先级线程持有的锁)。代码如下所示:
using(new LockAndElevate(myLock)) { ... code protected by myLock ... }我的理解是,这完全等同于
try { ml = new LockAndElevate(myLock)); ... code ... } finally { ml.Dispose(); }但实际上,mono垃圾收集器似乎得出结论,在我的受保护代码中没有对锁定对象的引用(第一个示例中没有使用变量),垃圾收集器在“受保护”的代码块中收集它。当我将代码更改为:
using(var tmp = new LockAndElevate(myLock)) { ... code ... }因此,通过添加一个我从未引用过的变量,我可以防止过早的GC。但是在语义上,他们应该能够进行代码分析,并意识到tmp变量没有被引用,删除"var tmp =“部分,这时他们可能会再次错误地过早地收集我包装的锁。因此,我的修复让我担心,因为将来对Mono的编译器改进可能会再次打破这一逻辑。
是我错了,还是这是一个单声道编译器错误?
发布于 2016-03-04 00:50:48
好吧,对于那些将来可能会读到这篇文章的人,我将总结一下人们一直在说的话:
()操作。
我希望我的总结是正确的。为了我自己的目的,我可能会采纳埃里克的建议。另一方面,这使得一段优雅的代码变得非常丑陋,事实证明,只需分配一个临时变量,虽然有点丑陋,但确实解决了问题(目前)。另外,正如上面所解释的,C#规范本身可能需要在这一特定方面进行发展,因此,Mono行为很可能会被声明为“不正确”。因此,也许我还不会让我的代码变得非常粗俗和令人厌恶!
https://stackoverflow.com/questions/35756775
复制相似问题