我在主要使用Knockout构建的非常大的单页Web应用程序中诊断分离的DOM树内存泄漏时遇到了问题.
我已经调整了应用程序,将虚拟FooBar对象附加到特定的HTML按钮元素,当用户移动到应用程序的不同"页面"时,该元素应该被垃圾收集.使用Chrome的堆快照功能,我可以看到一个旧的FooBar实例(应该是GC)仍然可以从HTMLButtonElement(大)分离的DOM树中访问它.
通过保留树面板跟踪参考,我跟随链从GC根部减少距离.但是,在某些时候,我的搜索在离根的节点距离4处达到死胡同(在这种情况下)!保留树根本不报告对此节点的引用,但不知何故知道它是GC根目录的四个步骤.
这是保留树的一部分让我感到困惑(右边的数字是距离根部的距离):
v foobar in HTMLButtonElement 10
v [4928] in Detached DOM tree / 5643 entries 9
v native in HTMLOptionElement 8
v [0] in Array 7
v mappedNodes 6
v [870] in Array 5
v itemsToProcess in system / Context 4
context in function itemMovedOrRetained()
context in function callCallback()
Run Code Online (Sandbox Code Playgroud)
保留树在距离3或以上不显示参考.
任何人都可以向我解释这个吗?我希望我能够跟随参考链回到JavaScript应用程序代码中令人讨厌的部分 - 但这让我陷入困境!
我正在构建一个C#表达式到Javascript的转换器,沿着Linq-to-SQL的路线,但我遇到了编译器生成的表达式树的问题.
我遇到的特殊问题是处理MemberExpression编译器生成的值,但是没有CompilerGeneratedAttribute在其类型上指定的值.
这是我一直在尝试的简化版本:
void ProcessMemberExpression(MemberExpression memberX) {
var expression = memberX.Expression;
var expressionType = expression.Type;
var customAttributes = expressionType.GetCustomAttributes(true);
var expressionTypeIsCompilerGenerated = customAttributes.Any(x => x is CompilerGeneratedAttribute);
if (expressionTypeIsCompilerGenerated) {
var memberExpressionValue = Expression.Lambda(memberX).Compile().DynamicInvoke();
... do stuff ...
}
else {
... do other stuff ...
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我打开了一个Visual Studio调试会话,我发现它(在立即窗口中运行):
expressionType.Name
"<>c__DisplayClass64"
expressionType.GetCustomAttributes(true)
{object[0]}
expressionType.GetCustomAttributes(true).Length
0
Run Code Online (Sandbox Code Playgroud)
所以我在这里有一个显然是编译器生成的类,没有自定义属性,因此没有CompilerGeneratedAttribute!因此,do other stuff当我打算公正时,我的代码将会do stuff.
如果有人能帮助我,我会非常感激.如果可能的话,我真的宁愿做任何肮脏的事情就像匹配类似的expressionType.Name东西<>.*__DisplayClass.
我一直在阅读learn.knockout.js教程并进行了实验.有人可以解释为什么这有效[ 教程:单页面应用程序,第2步 ](使用with: chosenFolderData和foreach: mails):
<!-- Mails grid -->
<table class="mails" data-bind="with: chosenFolderData">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="foreach: mails">
<tr>
<td data-bind="text: from"></td>
<td data-bind="text: to"></td>
<td data-bind="text: subject"></td>
<td data-bind="text: date"></td>
</tr>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
但不是这个(仅使用foreach: chosenFolderData.mails):
<!-- Mails grid -->
<table class="mails">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="foreach: chosenFolderData.mails">
<tr>
<td data-bind="text: from"></td>
<td data-bind="text: to"></td>
<td data-bind="text: subject"></td>
<td data-bind="text: date"></td>
</tr>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
我怀疑这是因为虽然chosenFolderData是可观察的,但事实chosenFolderData.mails并非如此.任何人都可以告诉我吗?
非常感谢!
- 拉尔夫
这就是我想做的事情.
我想写这样的POCO类:
[AutoExtended]
public partial class Foo {
public int Bar;
public string Baz;
}
Run Code Online (Sandbox Code Playgroud)
最好是在我的解决方案中的任意文件中([AutoExtend]属性是我刚刚编写的用于识别interes类的东西).
我希望构建过程从(a)AutoExtend在我的源代码中查找这些类开始,以及(b)自动生成如下的扩展:
public partial class Foo {
public static SomeType<int> Bar(Foo x) { ... };
public static SomeOtherType<string> Baz(Foo x) { ... };
}
Run Code Online (Sandbox Code Playgroud)
在编译解决方案之前.
有谁知道如何最好地做到这一点?我想罗斯林是要走的路,但我愿意接受建议.理想情况下,我想要一个解决方案,除了AutoExtend属性之外,用户方面不需要额外的"管道" .
(如果有人感兴趣的话,我正在用C#类编写一个域特定语言,并且运算过载,以上情况会使DSL使用起来更加舒适.)