The WorkerThread aspect is a really cheap way of running a method asynchronously in the thread pool. Sure, you don’t get to pick priority and such, but for a general-puspose background task, it’s perfect:

[Serializable]
public class WorkerThreadAttribute : OnMethodInvocationAspect
{
  public override void OnInvocation(MethodInvocationEventArgs eventArgs)
  {
    ThreadPool.QueueUserWorkItem(state => eventArgs.Proceed());
  }
}

There’s one problem with this method, though – it becomes more difficult to catch exceptions. For example, if you have a VS add-in throwing an exception on a separate thread, VS itself will not catch it and your add-in will crash. The solution? Another aspect:

[Serializable]
public class ExceptionDialogAttribute : OnExceptionAspect
{
  public override void OnException(MethodExecutionEventArgs eventArgs)
  {
    ExceptionMessageBox emb = new ExceptionMessageBox(
      eventArgs.Exception,
      ExceptionMessageBoxButtons.OK,
      ExceptionMessageBoxSymbol.Error);
    emb.Show(null);
  }
}

Rather than using a boring MessageBox to report the exception, I went for a richer user interface – namely, the ExceptionMessageBox that comes with SQL Server. Just what the doctor ordered.