object ExampleTickedScheduler : Thread() { val tasks = ConcurrentLinkedQueue() fun runTask(task: Runnable) { tasks += task } fun isMainThread() = Thread.currentThread() === this override fun run() { tasks.removeIf { it.run(); true } } init { start() } } object ExampleSchedulerDispatcher : CoroutineDispatcher() { //This context represents the context currently being //used on the main thread. Resume from it preferentially. internal var context: CoroutineContext = ExampleSchedulerDispatcher override fun dispatch(context: CoroutineContext, block: Runnable) { fun execute() { val current = this.context try { this.context = context; block.run() } finally { this.context = current } } if (ExampleTickedScheduler.isMainThread()) execute() else ExampleTickedScheduler.runTask(::execute) } } fun blocking(block: suspend CoroutineScope.() -> (Return)) = runBlocking(ExampleSchedulerDispatcher.context, block)