Quello che voglio fare è cambiare il modo in cui un metodo C # viene eseguito quando viene chiamato, in modo da poter scrivere qualcosa del genere:
[Distributed]
public DTask<bool> Solve(int n, DEvent<bool> callback)
{
for (int m = 2; m < n - 1; m += 1)
if (m % n == 0)
return false;
return true;
}
In fase di esecuzione, devo essere in grado di analizzare i metodi che hanno l'attributo Distributed (cosa che posso già fare) e quindi inserire il codice prima che il corpo della funzione venga eseguito e dopo che la funzione ritorna. Ancora più importante, devo essere in grado di farlo senza modificare il codice in cui viene chiamato Solve o all'inizio della funzione (in fase di compilazione; farlo in fase di esecuzione è l'obiettivo).
Al momento ho provato questo bit di codice (supponiamo che t sia il tipo in cui è memorizzato Solve e m sia un MethodInfo di Solve) :
private void WrapMethod(Type t, MethodInfo m)
{
// Generate ILasm for delegate.
byte[] il = typeof(Dpm).GetMethod("ReplacedSolve").GetMethodBody().GetILAsByteArray();
// Pin the bytes in the garbage collection.
GCHandle h = GCHandle.Alloc((object)il, GCHandleType.Pinned);
IntPtr addr = h.AddrOfPinnedObject();
int size = il.Length;
// Swap the method.
MethodRental.SwapMethodBody(t, m.MetadataToken, addr, size, MethodRental.JitImmediate);
}
public DTask<bool> ReplacedSolve(int n, DEvent<bool> callback)
{
Console.WriteLine("This was executed instead!");
return true;
}
Tuttavia, MethodRental.SwapMethodBody funziona solo su moduli dinamici; non quelli che sono già stati compilati e memorizzati nell'assembly.
Quindi sto cercando un modo per eseguire in modo efficace SwapMethodBody su un metodo che è già archiviato in un assembly caricato ed in esecuzione .
Nota, non è un problema se devo copiare completamente il metodo in un modulo dinamico, ma in questo caso devo trovare un modo per copiare attraverso l'IL e aggiornare tutte le chiamate a Solve () in modo che indicherebbe la nuova copia.