title: Remoting sponsor stops being called
body: <p>I've got an app which creates several AppDomains in a single process and communicates between them via remoting. I create sponsors for all objects to prevent them from being GCed.</p>
  
  <p>But, some ended up being GCed anyway. After some investigation I've determined that depending on the <code>InitialLeaseTime</code> set on my remote objects, my sponsors are either never called or get called a couple times and then never again.</p>
  
  <p><strong>My sponsor</strong> (I've removed some sanity checking for brevity):</p>
  
  <pre><code>class Sponsor : MarshalByRefObject, ISponsor, IDisposable
  {
      ILease lease;
  
      public Sponsor(MarshalByRefObject mbro)
      {
          lease = (ILease)RemotingServices.GetLifetimeService(mbro);
          lease.Register(this);
      }
  
      public TimeSpan Renewal(ILease lease)
      {
          return this.lease != null ? lease.InitialLeaseTime : TimeSpan.Zero;
      }
  
      public void Dispose()
      {
          if(lease != null)
          {
              lease.Unregister(this);
              lease = null;
          }
      }
  }
  </code></pre>
  
  <p><strong>My test case</strong>:</p>
  
  <pre><code>class Program : MarshalByRefObject
  {
      static void Main(string[] args)
      {
          AppDomain ad = AppDomain.CreateDomain("Remote");
  
          Program obj = (Program)ad.CreateInstanceAndUnwrap(
              typeof(Program).Assembly.FullName,
              typeof(Program).FullName);
  
          using (new Sponsor(obj))
          {
              // sleep for 6 minutes.
              // 5 seems to be the point where it gets GCed.
              Thread.Sleep(6 * 60 * 1000); 
  
              // throws a RemotingException
              obj.Ping();
          }
      }
  
      void Ping()
      {
      }
  
      public override object InitializeLifetimeService()
      {
          ILease lease = (ILease)base.InitializeLifetimeService();
  
          if (lease.CurrentState == LeaseState.Initial)
          {
              // this is the .NET default. if used, the lease is never renewed.
              //lease.InitialLeaseTime = TimeSpan.FromMinutes(5);
  
              // if uncommented, lease is renewed twice and never again.
              //lease.InitialLeaseTime = TimeSpan.FromMinutes(2);
  
              // if uncommented, lease is renewed continually.
              //lease.InitialLeaseTime = TimeSpan.FromMinutes(1);
          }
  
          return lease;
      }
  }
  </code></pre>
  
  <p>If I leave the <code>InitialLeaseTime</code> at 5 minutes, the .NET default, my sponsor will never be called. If I set it to 2 minutes, it will be called twice and then never again. If I set it to 1 minute, it will be called continually and work how I expected the default values to work.</p>
  
  <p><strong>Update</strong></p>
  
  <p>I've since determined that the <code>ILease</code> objects of my sponsors themselves are being GCed. They start out with the default 5min lease time, which explains how often my sponsors are being called. When I set my <code>InitialLeaseTime</code> to 1min, the <code>ILease</code> objects are continually renewed due to their <code>RenewOnCallTime</code> being the default of 2min.</p>
  
  <p>What am I doing wrong? I don't see a way to create sponsors for the lease objects of my sponsors.</p>