简体   繁体   English

如何在给定时间保留对对象状态的引用?

[英]How can I keep a ref to an object's state at a given time?

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.所以我可以在任何 C# 项目中使用它。

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.为此,我需要访问所有导致异常的嵌套方法以及所有方法的参数。

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.到目前为止,我使用了 postsharp OnMethodBoundaryAspect,它允许我定义 OnEntry、OnSucess 和 OnException 方法,每当方法:输入、返回或引发异常时都会调用这些方法。 What is great is that I can apply this aspect with a postsharp.config file in the project I want.很棒的是,我可以在我想要的项目中使用postsharp.config文件应用这个方面。 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.使用它,我可以维护自己的调用堆栈,并且可以保存对方法名称的引用,以及对方法参数的引用。

Now let's say a methodA calls a methodB which calls a methodC .现在,让我们说methodA调用methodB它调用一个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 ).所以,如果methodA参数在修改methodC只是抛出一个异常之前,当我序列调用堆栈,我们将看到一个调用堆栈methodA有一个错误值的参数(我们会看到在设定值methodC )。

I want to fix this issue and I considered using:我想解决这个问题,我考虑使用:

  1. deepcloning in the OnEntry method to copy all the methods parameters but that would lead to awful performances在 OnEntry 方法中进行深度克隆以复制所有方法参数,但这会导致糟糕的性能
  2. PostSharp LocationInterceptorAspect but that requires a paid licence PostSharp LocationInterceptorAspect 但这需要付费许可证
  3. VEH Hooking but it is incredibly slow and it would probably be faster to use deepcloning VEH Hooking 但它非常慢,使用deepcloning可能会更快

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)?有没有其他方法可以让我以比deepcloning更好的性能及时保存对象的状态,或者至少让我拦截对指定对象带来的所有修改(例如 VEH 挂钩或 LocationInterceptor Aspect)?

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. PS:我不能使用IOnPropertyChange或类似的东西,因为我不能接触任何现有的源代码,除非我可以在运行时实现它们,但我没有看到任何可能的地方。

Considering that I didn't want to implement any specific code in the object that needed to be monitered I had only 2 options :考虑到我不想在需要监控的对象中实现任何特定代码,我只有 2 个选项:

  1. Serialization or any deepcloning method whenever a state need to be saved (I used JSON.NET for this solution)每当需要保存状态时的序列化或任何深度克隆方法(我在此解决方案中使用了 JSON.NET)

  2. 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:记录对对象进行的所有修改,以便在必要时将其反转 => 在发生修改时收到通知我探索了所有这些技术:

    • Postsharp with the LocationInterceptionAspect (not free)带有LocationInterceptionAspect 的Postsharp(不是免费的)
    • 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 Harmony 2允许拦截任何函数调用(在我的情况下是属性的 setter 函数),如果您可以放弃任何字段更改,最简单和最简单的工作解决方案
    • VEH hooking, would work in theory but extremely slow and I didn't explore it that much because of its complexity VEH 挂钩,理论上可行,但速度非常慢,由于它的复杂性,我没有过多探索它
    • Editing the MSIL code of a function to hook all the stfld instruction. 编辑函数的 MSIL 代码以挂钩所有stfld指令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何保持对象在其原始位置/旋转范围内旋转,而不在每次新旋转时都添加/删除? - How can I keep the object to rotate in the range from it's original position/rotation and not to add/remove each time a new rotation? 给定线程的 id 或句柄,我如何确定线程的状态? - Given a thread's id or handle, how can I determine the thread's state? 如何将int传递给接受“ ref object”的函数 - How can I pass an int to a function that takes in 'ref object' 给定本地时区和目标时区,我如何找到目标的当前时间C# - Given a local timezone and a target timezone how can I find the target's current time C# 如何跟踪DRY-ly状态? - How can I keep track of state DRY-ly? 如何在更新对象状态时使命令同步? - How can I make a command synchronous when updating an object's state? 如何在给定 UTC 时间和日期的情况下创建 DateTime 对象? - How do I create a DateTime object given UTC time and date? 如何在Main()中使用方法(其参数已由ref传递)的返回值 - How can I use a method's (whose argument has been passed by ref) return value in Main() 如何避免引用参数? - How can I avoid ref parameters? 如何创建一个倒计时到给定时间和日期的计数器? - How can I create a counter that counts down to a given time and date?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM