public static void Explain(this GoodCitizen runnable, TextWriter writer)
    {
        writer.WriteLine(@"
- Is async all the way and embraces virality of the API where it makes sense (IO-bound path)
- Async void methods will crash the process if an exception is thrown
- `Task`-returning methods are better since unhandled exceptions trigger the `TaskScheduler.UnobservedTaskException`
- Be ware that only when the finalizers are run the unobserved exception is thrown
- Does not explicitely offload to the worker thread pool by using `Task.Run` or `Task.Factory.StartNew` (offloading is a concern of the caller)
- Returns `Task`, `Task<TResult>`, `ValueTask` or `ValueTask<TResult>`
- Accepts `CancellationToken` if cancellation is appropriate. It is OK to add it but not respect it. Cancellation is cooperative.
- Tries to respect token where it can and makes sense
- Disposes owned `CancellationTokenSource` (due to allocated Timer instances when used with `CancelAfter`)
- Disposes owned `CancelationTokenRegistration` to not leak memory
- For high-perf scenarios avoid closure capturing in token registrations
- For library or framework code uses `ConfigureAwait(false)` to opt-out from context capturing if not needed
- Can used linked token sources for internal SLAs and cancellation scenarios
- Favours simple sequential async execution over explicit concurrency (concurrency is hard)
- No silver bullet that magically makes your DB query fasters ;)
");
    }
 public static void PrintEnd(this GoodCitizen runnable)
 {
     Console.WriteLine($"End on {Thread.CurrentThread.ManagedThreadId}");
 }