CLR AddIn Model in Paint.Net – 9 (LifetimeToken and LifetimeTokenHandle)

AddIn can be passed to multiple Hosts, or it can have multiple references for the same Host. How to manage the lifetime of an AddIn becomes a big challenge. In the old COM world, we would do reference counting; allowing each AddIn increment the reference count by one. Reference counting is an algorithm that could generate really nasty bugs. Anyone can dereference the count multiple times, leave the crime scene and crash others code. Our design is to completely blocking people to do that. Each reference of the same AddIn will get a different token. We call this a LifetimeToken.

 

An AddIn will implement IContract. It will have to implement AcquireLifetimeToken and RevokeLifetimeToken (we recommend inherit the functionality from ContractBase). Now the new question becomes when should we call these two APIs and how to store the tokens. In general, we recommend people to AcquireLifetimeToken immediately after they receive a contract and call RevokeLifetimeToken after you are done with the Contract. To help make the developer’s life better, we created a class called LifetimeTokenHandle and used it the way we did in the HostAdapter.

 

    [HostAdapter]

    public class PDNHostAdapter : AddInHSV

    {

        IPDNEffectContract contract;

        LifetimeTokenHandle handle;

        public PDNHostAdapter(IPDNEffectContract contract)

        {

            this.contract = contract;

            handle = new LifetimeTokenHandle(contract);

        }

        public override void Render(EffectConfigToken parameters, PaintDotNet.RenderArgs dstArgs, PaintDotNet.RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length)

        {

            contract.Render(new RenderArgsContractAdapter(dstArgs), new RenderArgsContractAdapter(srcArgs), rois, startIndex, length);

        }

    }

 

A few benefits of using LifetimeTokenHandle are

  • The coding pattern is really simple.
  • You won’t worry about where to store the Token
  • AcquireLifetimeToken happens automatically in the Handle’s constructor.
  • You won’t forget to release the token because we will have LifetimeTokenHandle finalizer do the work as soon as GC happened.
  • Even you acquire token twice won’t really hurt in most scenario.
  • Others code won’t be able to revoke your tokens by mistake.

 

What happens if I forget to AcquireLifetimeToken?

The contract will be good for use for about 5 minutes. After that, remoting infrastructure will treat the AddIn as there is no live reference and it remove it from its internal hash table. If you see a remoting exception while using a contract, that is probably what has happened.

 

Next topic will be treat data type as contract.