Background thread work runner

Implement a work runner that enqueues works on a thread and dequeues/executes them one by one. Disposing the work runner cancels the dequeuing/executing thread as soon as it is possible.