如何在给定的时间保持对对象状态的引用? [英] How can I keep a ref to an object's state at a given time?
问题描述
我的目标是在引发异常时将调用堆栈状态保存在文件中.但是我有一个主要的限制:我无法触及任何现有代码.我的目标是在我不了解当前工作流程的情况下实现这一目标.所以我可以在任何C#项目中使用它.
My goal is to save in a file the callstack state when an exception is raised. But I have one major restraint: I cannot touch any of the existing code. My goal is to implement that in a context where I'm unaware of the current workflow. So I can use it in any C# Project.
为此,我需要访问所有导致异常的嵌套方法以及所有方法的参数.
To do so I need to have access to all the nested methods that lead to the exception but also all the method's arguments.
直到现在,我一直使用postharsh的OnMethodBoundaryAspect,该方法使我可以定义OnEntry,OnSucess和OnException方法,无论何时输入方法:,返回或引发异常,该方法都将被调用.很棒的是,我可以在所需项目中的 postsharp.config
文件中应用此方面.没有源代码修改,我只将我的项目添加到解决方案中,一个配置文件,并在解决方案的每个项目中引用我的项目,我很高兴.使用它,我可以维护自己的调用堆栈,并且可以保存对方法名称的引用以及对方法参数的引用.
Until now I used postsharp OnMethodBoundaryAspect which allow me to define OnEntry, OnSucess, and OnException method that is called whenever a method: is entered, returns, or raise an exception. What is great is that I can apply this aspect with a postsharp.config
file in the project I want. No source modification, I'm only adding my project to the solution, a config file, and reference to my project in every project of the solution and I'm good to go. Using that I could maintain a callstack of my own, and I could save references to methods' name, and ref to methods' arguments.
现在,假设 methodA
调用了 methodB
,这又调用了 methodC
.
Now let's say a methodA
calls a methodB
which calls a methodC
.
除了明显使用引用之外,我所做的工作效果很好.因此,如果在引发异常之前在 methodC
中修改了 methodA
参数,则当我序列化调用堆栈时,我们将看到一个调用堆栈,其中 methodA
的参数值有误(我们将在 methodC
中看到设置的值).
What I've done works well except that obviously I use references. So if methodA
argument is modified in methodC
just before raising an exception, when I serialize the call stack, We'll see a call stack where methodA
has an argument with a wrong value (we'll see the value set in methodC
).
我想解决此问题,并考虑使用:
I want to fix this issue and I considered using:
- 在OnEntry方法中进行深克隆以复制所有方法参数,但这会导致糟糕的性能
- PostSharp LocationInterceptorAspect,但需要付费许可证
- VEH挂接,但是它非常慢,并且使用
deepcloning
可能会更快
- deepcloning in the OnEntry method to copy all the methods parameters but that would lead to awful performances
- PostSharp LocationInterceptorAspect but that requires a paid licence
- VEH Hooking but it is incredibly slow and it would probably be faster to use
deepcloning
是否有其他方法可以使我及时保存对象的状态,从而获得比 deepcloning
更好的性能,或者至少让我拦截对指定对象进行的所有修改(例如VEH挂钩还是LocationInterceptor方面)?
Is there any other way that would allow me to save the state of an object in time with greater performances than deepcloning
, or at least let me intercept all modifications brought to a specified object (like the VEH hooking or the LocationInterceptor Aspect)?
PS:我不能使用 IOnPropertyChange
或类似的东西,因为我无法触摸任何现有的sourceCode,除非我可以在运行时实现它们,但是我看不到它的任何地方可能.
PS: I can't use IOnPropertyChange
or things like that because I can't touch any of the existing sourceCode except if I can implement them at runtime but I didn't see anywhere that it was possible.
推荐答案
考虑到我不想在需要监控的对象中实现任何特定代码,我只有两个选择:
Considering that I didn't want to implement any specific code in the object that needed to be monitered I had only 2 options :
-
序列化或任何需要保存状态的深克隆方法(我将JSON.NET用于此解决方案)
Serialization or any deepcloning method whenever a state need to be saved (I used JSON.NET for this solution)
记录所有带给对象的修改,以便在必要时将其撤消=>在进行修改时得到通知,我探索了所有这些技术:
Logging all modification brought to the object in order to reverse them if necessary => to be notified when a modification will occur I explored all ths techniques:
- 使用 LocationInterceptionAspect (不是免费)
- Harmony 2 允许拦截任何函数调用(在我的情况下是属性的setter函数)),如果您可以放弃任何字段更改,则是最简单,最简单的工作解决方案
- VEH挂接在理论上可以正常运行,但速度非常慢,由于其复杂性,我没有对其进行太多探讨
- 编辑MSIL函数的代码来挂钩所有
stfld
指令.
- Postsharp with the LocationInterceptionAspect (not free)
- Harmony 2 which allow to intercept any function call (and in my case the setter function of properties), simplest and easiest working solution if you can discard any field changes
- VEH hooking, would work in theory but extremely slow and I didn't explore it that much because of its complexity
- Editing the MSIL code of a function to hook all the
stfld
instruction.
这篇关于如何在给定的时间保持对对象状态的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!