Repository: Kotlin/kotlinx.coroutines
File: ui/kotlinx-coroutines-android/src/HandlerDispatcher.kt (Kotlin)

Code before:
        if (!handler.post(block)) {
            cancelOnRejection(context, block)
        }
    }

    override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
        val block = Runnable {
            with(continuation) { resumeUndispatched(Unit) }
        }
        if (handler.postDelayed(block, timeMillis.coerceAtMost(MAX_DELAY))) {
            continuation.invokeOnCancellation { handler.removeCallbacks(block) }
        } else {
            cancelOnRejection(continuation.context, block)
        }
    }

    override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle {
        if (handler.postDelayed(block, timeMillis.coerceAtMost(MAX_DELAY))) {
            return DisposableHandle { handler.removeCallbacks(block) }
        }
        cancelOnRejection(context, block)
        return NonDisposableHandle
    }

    private fun cancelOnRejection(context: CoroutineContext, block: Runnable) {
        context.cancel(CancellationException("The task was rejected, the underlying handler '$handler' was closed"))
        Dispatchers.IO.dispatch(context, block)
    }

    override fun toString(): String = toStringInternalImpl() ?: run {
        val str = name ?: handler.toString()
        if (invokeImmediately) "$str.immediate" else str
    }

    override fun equals(other: Any?): Boolean = other is HandlerContext && other.handler === handler
    override fun hashCode(): Int = System.identityHashCode(handler)
}

@Volatile
private var choreographer: Choreographer? = null

/**
 * Awaits the next animation frame and returns frame time in nanoseconds.
 */
public suspend fun awaitFrame(): Long {
    // fast path when choreographer is already known
    val choreographer = choreographer
    if (choreographer != null) {
        return suspendCancellableCoroutine { cont ->
            postFrameCallback(choreographer, cont)
        }

Review comment (suggestion):
```suggestion
        context.cancel(CancellationException("The task was rejected, the handler '$handler' underlying the dispatcher was closed"))
```
Still think that employing `name` (for example, by calling `toString`) better reflects the user intent of supplying the `name`, but it's your call.

Code after:
        if (!handler.post(block)) {
            cancelOnRejection(context, block)
        }
    }

    override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
        val block = Runnable {
            with(continuation) { resumeUndispatched(Unit) }
        }
        if (handler.postDelayed(block, timeMillis.coerceAtMost(MAX_DELAY))) {
            continuation.invokeOnCancellation { handler.removeCallbacks(block) }
        } else {
            cancelOnRejection(continuation.context, block)
        }
    }

    override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle {
        if (handler.postDelayed(block, timeMillis.coerceAtMost(MAX_DELAY))) {
            return DisposableHandle { handler.removeCallbacks(block) }
        }
        cancelOnRejection(context, block)
        return NonDisposableHandle
    }

    private fun cancelOnRejection(context: CoroutineContext, block: Runnable) {
        context.cancel(CancellationException("The task was rejected, the handler underlying the dispatcher '${toString()}' was closed"))
        Dispatchers.IO.dispatch(context, block)
    }

    override fun toString(): String = toStringInternalImpl() ?: run {
        val str = name ?: handler.toString()
        if (invokeImmediately) "$str.immediate" else str
    }

    override fun equals(other: Any?): Boolean = other is HandlerContext && other.handler === handler
    override fun hashCode(): Int = System.identityHashCode(handler)
}

@Volatile
private var choreographer: Choreographer? = null

/**
 * Awaits the next animation frame and returns frame time in nanoseconds.
 */
public suspend fun awaitFrame(): Long {
    // fast path when choreographer is already known
    val choreographer = choreographer
    if (choreographer != null) {
        return suspendCancellableCoroutine { cont ->
            postFrameCallback(choreographer, cont)
        }