I'm having the problem described in this message board post.
I have an object that is hosted in its own AppDomain.
public class MyObject : MarshalByRefObject
{
    public event EventHandler TheEvent;
    ...
    ...
}
I'd like to add a handler to that event. The handler will run in a different AppDomain. My understanding is this is all good, events get delivered across that boundary magically, with .NET Remoting.
But, when I do this:
// instance is an instance of an object that runs in a separate AppDomain
instance.TheEvent += this.Handler ; 
...it compiles fine but fails at runtime with:
System.Runtime.Remoting.RemotingException: 
     Remoting cannot find field 'TheEvent' on type 'MyObject'.
Why?
EDIT: source code of working app that demonstrates the problem:
// EventAcrossAppDomain.cs
// ------------------------------------------------------------------
//
// demonstrate an exception that occurs when trying to use events across AppDomains.
//
// The exception is:
// System.Runtime.Remoting.RemotingException:
//       Remoting cannot find field 'TimerExpired' on type 'Cheeso.Tests.EventAcrossAppDomain.MyObject'.
//
// compile with:
//      c:\.net3.5\csc.exe /t:exe /debug:full /out:EventAcrossAppDomain.exe EventAcrossAppDomain.cs
//
using System;
using System.Threading;
using System.Reflection;
namespace Cheeso.Tests.EventAcrossAppDomain
{
    public class MyObject : MarshalByRefObject
    {
        public event EventHandler TimerExpired;
        public EventHandler TimerExpired2;
        public  MyObject() { }
        public void Go(int seconds)
        {
            _timeToSleep = seconds;
            ThreadPool.QueueUserWorkItem(Delay);
        }
        private void Delay(Object stateInfo)
        {
            System.Threading.Thread.Sleep(_timeToSleep * 1000);
            OnExpiration();
        }
        private void OnExpiration()
        {
            Console.WriteLine("OnExpiration (threadid={0})",
                              Thread.CurrentThread.ManagedThreadId);
            if (TimerExpired!=null)
                TimerExpired(this, EventArgs.Empty);
            if (TimerExpired2!=null)
                TimerExpired2(this, EventArgs.Empty);
        }
        private void ChildObjectTimerExpired(Object source, System.EventArgs e)
        {
            Console.WriteLine("ChildObjectTimerExpired (threadid={0})",
                              Thread.CurrentThread.ManagedThreadId);
            _foreignObjectTimerExpired.Set();
        }
        public void Run(bool demonstrateProblem)
        {
            try 
            {
                Console.WriteLine("\nRun()...({0})",
                                  (demonstrateProblem)
                                  ? "will demonstrate the problem"
                                  : "will avoid the problem");
                int delaySeconds = 4;
                AppDomain appDomain = AppDomain.CreateDomain("appDomain2");
                string exeAssembly = Assembly.GetEntryAssembly().FullName;
                MyObject o = (MyObject) appDomain.CreateInstanceAndUnwrap(exeAssembly,
                                                                          typeof(MyObject).FullName);
                if (demonstrateProblem)
                {
                    // the exception occurs HERE
                    o.TimerExpired += ChildObjectTimerExpired;
                }
                else
                {
                    // workaround: don't use an event
                    o.TimerExpired2 = ChildObjectTimerExpired;
                }
                _foreignObjectTimerExpired = new ManualResetEvent(false);
                o.Go(delaySeconds);
                Console.WriteLine("Run(): hosted object will Wait {0} seconds...(threadid={1})",
                                  delaySeconds,
                                  Thread.CurrentThread.ManagedThreadId);
                _foreignObjectTimerExpired.WaitOne();
                Console.WriteLine("Run(): Done.");
            }
            catch (System.Exception exc1)
            {
                Console.WriteLine("In Run(),\n{0}", exc1.ToString());
            }
        }
        public static void Main(string[] args)
        {
            try 
            {
                var o = new MyObject();
                o.Run(true);
                o.Run(false);
            }
            catch (System.Exception exc1)
            {
                Console.WriteLine("In Main(),\n{0}", exc1.ToString());
            }
        }
        // private fields
        private int _timeToSleep;
        private ManualResetEvent _foreignObjectTimerExpired;
    }
}