加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp-classic – VBScript似乎是来自嵌套作用域的GC’对象,顺序错

发布时间:2020-12-16 07:27:12 所属栏目:asp.Net 来源:网络整理
导读:我有以下代码: function p (str) Response.Write VBLF strend functionfunction nop: end functionclass Test1 private sub class_initialize p "Test1 Start" end sub private sub class_terminate p "Test1 End" end subend classclass Test2 private sub
我有以下代码:

function p (str)
    Response.Write VBLF & str
end function

function nop: end function

class Test1
    private sub class_initialize
        p "Test1 Start"
    end sub

    private sub class_terminate
        p "Test1 End"
    end sub
end class

class Test2
    private sub class_initialize
        p "    Test2 Start"
    end sub

    private sub class_terminate
        p "    Test2 End"
    end sub
end class

当我跑:

with new Test1
    with new Test2
    end with
end with

我期待输出:

Test1 Start
    Test2 Start
    Test2 End
Test1 End

但我得到:

Test1 Start
    Test2 Start
Test1 End
    Test2 End

但是,如果我运行以下任一项,我会得到我的预期:

with new Test1
    with new Test2
        nop
    end with
end with

with new Test1
    with new Test2
    end with
    nop
end with

但不是以下内容:

with new Test1
    nop
    with new Test2
    end with
end with

VBScript对GC的对象有相当强的保证,我在我的应用程序中使用(滥用?)这种保证用于各种目的.没有nop,为什么以“错误”的顺序收集Test1和Test2?

解决方法

多么迷人的bug.

我没有方便的VBScript引擎的调试版本. (自从我上次查看它以来的两年里,我保留它的十年硬盘显然已经坏了.)但是,我可以很容易地猜到这里发生了什么.我怀疑是我没有将对应于“end with”的指令标记为语句结束且收集器必须运行的点.

让我们考虑一下这个假设.

在您的第一个示例中,GC何时运行?程序结束时.此时,终结符按创建对象的顺序运行. (这是您不应该依赖的实现细节.)

在你的第二个和第三个例子中,对nop的调用结束会触发一个GC,这就发生在接下来的结尾处. (我不太清楚为什么第二个例子在对象有资格收集时触发GC;我不记得codegen的确切语义,用于从with block范围中弹出对象引用.)

在您的第四个示例中,GC在内部使用之前触发,并且不执行任何操作.

由于我写了终止逻辑和相当数量的“带”处理代码,我无疑造成了这个错误,所以很多道歉.很明显,在过去的十一年或十二年里,我们与它一起生活并没有出现重大问题,而且由于它只影响没有内容的“有”块,我不认为它会被修复.

无论如何,你不应该依赖终止令.这是一个糟糕的编程习惯.

有关VBScript终止逻辑的迷人主题的更多信息,请参阅:

What is the order of destruction of objects in VBScript?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读