I wrote two magical functions to handle my problem. I want to share it so that other users can benefit, too.
I added a host object referring to my Form object to the engine.
This avoids the application from hanging when it hits a breakpoint in the callback. (Remember that my debugger is hosted in a web browser inside my application)
And this is how I register to the "Resize" event of the form in the script:
I would be happy to your feedbacks!
I added a host object referring to my Form object to the engine.
engine.AddHostObject("main", this);
I added two public functions to the Form class: public EventHandler AddEventHandler(object obj, string eventName, object callback) {
var eventInfo = obj.GetType().GetEvent(eventName);
if (eventInfo != null)
{
Assembly asm = typeof(V8ScriptEngine).Assembly;
Type asmType = asm.GetType("Microsoft.ClearScript.DelegateFactory");
MethodInfo mi = asmType.GetMethod("CreateDelegate", new[] { typeof(ScriptEngine), typeof(object), typeof(Type) });
object[] parameters = { engine, callback, eventInfo.EventHandlerType };
Delegate scriptHandler = (Delegate)mi.Invoke(null, parameters);
EventHandler handler = delegate (object sender, EventArgs e) {
Console.WriteLine("Event triggered: " + eventInfo.Name);
new Thread(() =>
{
object[] args = new object[] { sender, e };
scriptHandler.DynamicInvoke(args);
}).Start();
};
eventInfo.AddEventHandler(obj, handler);
return handler;
}
return null;
}
public bool RemoveEventHandler(object obj, string eventName, EventHandler handler)
{
var eventInfo = obj.GetType().GetEvent(eventName);
if (eventInfo != null)
{
eventInfo.RemoveEventHandler(obj, handler);
return true;
}
return false;
}
What solves my problem is calling the callback script in a new Thread. This avoids the application from hanging when it hits a breakpoint in the callback. (Remember that my debugger is hosted in a web browser inside my application)
And this is how I register to the "Resize" event of the form in the script:
var handler = main.AddEventHandler(main, "Resize", function (sender, e) {
Console.WriteLine("Resize triggered inside script");
main.RemoveEventHandler(main, "Resize", handler); //unregister
});
The only restriction in this solution is that I can only register events whose method parameters match with the EventHandler delegate.I would be happy to your feedbacks!