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();
source share