How to report an event between application domains?

I have two application domains, one of which creates a child domain. There is a MarshalByRef object in the child domain, which is passed using .NET Remoting. An object running in the parent domain calls the wrapper for the remote object as part of the application function:

 public class ScanningTask : Task { private class Loader : MarshalByRef { public void Load(IEnumerable<string> paths) { ... } public event EventHandler<LoadEventArgs> OnLoad; } public void RunTask() { var domain = AppDomain.CreateDomain("LoadDomain"); var loader = (Loader)domain.CreateInstanceFromAndUnwrap( typeof(Loader).Assembly.Location, typeof(Loader).FullName); loader.Load(...); AppDomain.Unload(domain); } } 

Most of the code has been removed for brevity.

This Loader object provides an OnLoad event that I would like to capture in the parent domain. If I just add an event handler delegate, it will try to serialize the ScanningTask to the child domain and throw an exception because it is not serializable.

I really want the event to be broadcast across all domains. Any smart suggestions as to how?

+4
source share
1 answer

Based on this solution , you can also inherit the task of the Task class from MarshalByRefObject. This would solve the serialization problem as it would pass the serialized Cross-AppDomain link, which would be used to attach to the event.

 public class ScanningTask : MarshalByRefObject { private class Loader : MarshalByRefObject { public void Load() { if (OnLoad != null) OnLoad(this, EventArgs.Empty); } public event EventHandler OnLoad; } public void RunTask() { var domain = AppDomain.CreateDomain("LoadDomain"); var loader = (Loader)domain.CreateInstanceFromAndUnwrap( typeof(Loader).Assembly.Location, typeof(Loader).FullName); loader.OnLoad += new EventHandler(loader_OnLoad); loader.Load(); AppDomain.Unload(domain); } void loader_OnLoad(object sender, EventArgs e) { Console.Write("load event called"); } } 

If, for existing codebase bases, the base class Task cannot be executed to inherit from MarshalByRefObject, your solution may be a proxy class that inherits from Loader (hence, MarshalByRefObject itself) and call forwarding to the actual deployed instance.

 public class ScanningTask { private class Loader : MarshalByRefObject { public virtual void Load() { RaiseOnLoad(this); } protected void RaiseOnLoad(Loader loader) { if (OnLoad != null) OnLoad(loader, EventArgs.Empty); } public event EventHandler OnLoad; } private class LoaderProxy : Loader { public readonly Loader Instance; public LoaderProxy(Loader loaderInstance) { this.Instance = loaderInstance; this.Instance.OnLoad += new EventHandler((sender, e) => RaiseOnLoad(this.Instance)); } public override void Load() { this.Instance.Load(); } } public void RunTask() { var domain = AppDomain.CreateDomain("LoadDomain"); var loader = (Loader)domain.CreateInstanceFromAndUnwrap( typeof(Loader).Assembly.Location, typeof(Loader).FullName); var proxy = new LoaderProxy(loader); proxy.OnLoad += new EventHandler(loader_OnLoad); loader.Load(); // same as proxy.Load() AppDomain.Unload(domain); } void loader_OnLoad(object sender, EventArgs e) { Console.Write("load event called"); } } 
+5
source

All Articles