- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
今天,我发现了一种实现 INotifyPropertyChanged 接口(interface)的有趣方法。我们可以简单地调用 RaisePropertyChanged(); 而不是传递属性更改的字符串名称或 lambda 表达式。从 setter 中,标记调用是无参数的。这是 RaisePropertyChanged() 方法中的代码:
public virtual void RaisePropertyChanged()
{
var frames = new System.Diagnostics.StackTrace();
for (var i = 0; i < frames.FrameCount; i++)
{
var frame = frames.GetFrame(i).GetMethod() as MethodInfo;
if (frame != null)
if (frame.IsSpecialName && frame.Name.StartsWith("set_"))
{
RaisePropertyChanged(frame.Name.Substring(4));
return;
}
}
throw new InvalidOperationException("NotifyPropertyChanged() can only by invoked within a property setter.");
}
这是一个将通知其家属其更改的属性:
public string MyProperty
{
get { return _myField; }
set
{
_myField= value;
RaisePropertyChanged();
}
}
虽然我觉得这种方法很有趣,但我认为如果属性经常更改......或者如果我们应用程序中的每个属性都使用这种方法来通知其更改,性能损失可能会很严重。
我想听听你的意见。 (不再有 community-wiki 复选框?)这种方法是否非常效率低下?
最佳答案
我刚刚使用 this code 对其进行了测试. (请注意,我使用 limitation pointed out in Wim Coenen's answer 属性绕过了 MethodImpl。我怀疑这是否是万无一失的解决方法。)
结果:
Raised event using reflection 1000 times in 25.5334 ms.Raised event WITHOUT reflection 1000 times in 0.01 ms.
因此您可以看到,涉及堆栈跟踪的解决方案的成本是“正常”解决方案的大约 2,500 倍。
无论如何,这是成比例的答案。我个人不喜欢这个想法(尽管它可能很聪明),其原因远远超出了性能问题;但是,显然,这是您的决定。
编辑:作为记录,I felt compelled to write a blog post about this — 特别是,尽管性能受到影响,但一些开发人员仍会倾向于使用这样的方法。
无论您是否同意我对这个问题的看法(我意识到性能影响在绝对方面很小),我觉得真正的致命打击这个想法是,为了使它更加健壮,有必要使用 MethodImpl
属性装饰您打算从中调用 RaisePropertyChanged
的每个属性 setter ,传递 MethodImplOptions.NoInlining
... 就在那里,抵消了您通过其他方式获得的任何打字节省。
所以你在开发时间上留下了净损失(无论你花了多少秒来输入整个 MethodImpl
属性部分),加上性能惩罚。如果你问我,几乎没有理由走这条路。
关于c# - 这到底有多慢? INotifyPropertyChanged 使用 StackTrace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4520570/
我希望这个问题能够在 SO 的规则下存活下来,因为我进行了很多搜索,没有找到关于它的文档,有时甚至忽略了它,但这让我既不理解问题也不理解解决方案。 Exceptoion 的 StackeTrace 有
我正在Gradle项目中设置Spotbugs,但是当我运行它时,Spotbugs会生成输出报告,但是将失败的堆栈跟踪记录到控制台。我想知道是否有办法抑制它。 这是我的Gradle文件: buildsc
这是我执行类的主要方法的任务,该类在Java项目的build.gradle中定义: task(runClass, type: JavaExec) { try { main =
我遇到了一个意外错误,它创建了包含大量行和不同库的 stackTrace。如果从上到下阅读,可以看到除了第2-3个方法之外的每个被调用的方法。看起来像 //Pseudo code method1_1(
我正在尝试将 gradle java 应用程序部署到 heroku (基于 jhipster)。我可以使用“heroku local”在本地构建并运行它,但是当我尝试远程部署它时,当它尝试构建应用程序
以下异常: Exception in thread "main" java.lang.NullPointerException at javaapplication7.App.main(App.jav
我需要按关键字从日志文件中 grep 完整的堆栈跟踪。 这段代码工作正常,但在大文件上会变慢(比文件更慢)。 我认为改进正则表达式以查找关键字的最佳方法,但我无法完成。 #!/usr/bin/perl
我在托管应用程序中收到错误消息,我正在尝试了解错误发生的原因。 为此,我查看了错误页面上的堆栈跟踪,如下所示: [ NullReferenceException: Object reference n
我的日志库中有这段代码 var stackTrace = new StackTrace(); string operationName = stackTrace.GetFrame(1).GetMeth
我们正在运行多个 Sitecore 网站,并且刚刚收到反馈,在出现错误时向网站用户提供堆栈跟踪可能很危险。既然人们获得了堆栈跟踪信息,该网站是否会更容易受到黑客攻击? 最佳答案 这绝对是弊大于利。根据
我们正在使用 Rational Application Developer 7.5(基于 Eclipse 3.4)为 WebSphere Application Server 6.1 开发一个 Web
给定以下流畅的 API 调用: Foo() .Bar1(() => { ... }) .Bar2(() => { ... }) .Bar3(); 我想稍后确定代码文件和 Bar
在我使用 StackTrace 的代码中发生了一些奇怪的事情。几乎就像没有加载调试信息一样......但我正在 DEBUG 构建上运行它。.pdb 文件肯定在 bin 目录中并且是最新的。我的想法真的
我不断收到此错误,我似乎在网上找不到任何帮助。我是flutter和android studio的新手。非常感谢任何帮助 FAILURE:构建失败并出现异常。 Where: Build file 'C:
在我的项目的目标目录中,有一个名为 stacktrace.log 的文件。我已经意识到文件的大小已经超过 3 GB。删除这个文件对我来说安全吗?删除后是否会导致任何文件未找到异常?谢谢你的时间。 -
我知道 http://richhickey.github.com/clojure/clojure.stacktrace-api.html . 有没有办法在不抛出异常并捕获它的情况下获取当前的堆栈跟踪?
我有一个异常记录器,它将所有异常记录到日志文件中: class function TLogger.LogException (ACaller: String; E: Exception): Boole
有时我在jQuery UI js文件的一行中收到错误或未处理的异常。我知道问题是一个空或空的对象或属性传递给jQuery。例如,在Chrome浏览器中,我收到“未捕获的TypeError”错误。 做一
我只是通过使用全局函数(在我的情况下称为GetCallingMethod)进行了一些分析。 通常情况下,它的效果很好。但是在某些情况下,应用程序被阻止。当关闭应用程序时,它被阻止。在Visual St
我正在分析遗留应用程序中的错误,同时清理并改进它。我有一些堆栈跟踪被记录到数据库中,但是它存储的量有一个限制 (VARCHAR2(1000)),并且错误发生在 System.Data 的深处.....
我是一名优秀的程序员,十分优秀!