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

跟風遠走 提交于 2021-02-11 12:20:53

问题


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.

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.

Now let's say a methodA calls a methodB which calls a 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. 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

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: 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.


回答1:


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. Serialization or any deepcloning method whenever a state need to be saved (I used JSON.NET for this solution)

  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)
    • 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.


来源:https://stackoverflow.com/questions/64750335/how-can-i-keep-a-ref-to-an-objects-state-at-a-given-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!