如何在给定的时间保持对对象状态的引用? [英] How can I keep a ref to an object's state at a given time?

查看:58
本文介绍了如何在给定的时间保持对对象状态的引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是在引发异常时将调用堆栈状态保存在文件中.但是我有一个主要的限制:我无法触及任何现有代码.我的目标是在我不了解当前工作流程的情况下实现这一目标.所以我可以在任何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:

  1. 在OnEntry方法中进行深克隆以复制所有方法参数,但这会导致糟糕的性能
  2. PostSharp LocationInterceptorAspect,但需要付费许可证
  3. VEH挂接,但是它非常慢,并且使用 deepcloning
  4. 可能会更快
  1. deepcloning in the OnEntry method to copy all the methods parameters but that would lead to awful performances
  2. PostSharp LocationInterceptorAspect but that requires a paid licence
  3. 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 :

  1. 序列化或任何需要保存状态的深克隆方法(我将JSON.NET用于此解决方案)

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆