Skip to content

Instantly share code, notes, and snippets.

@Jason5Lee
Created July 27, 2019 04:58
Show Gist options
  • Save Jason5Lee/e5f402e2a187fdbfe8e36f6ebffbe5c3 to your computer and use it in GitHub Desktop.
Save Jason5Lee/e5f402e2a187fdbfe8e36f6ebffbe5c3 to your computer and use it in GitHub Desktop.
An example about abandoning coroutine in Kotlin may not execute the finally clause immediately

In Kotlin, a coroutine can be abandoned by not resuming it. If a coroutine is abandoned while suspending in a try-block with finally, the finally clause will not be executed until the coroutine is collected.

For example, the following Kotlin code

val seqWithFinally = sequence {
    try {
        yield(Unit)
        yield(Unit)
    } finally {
        println("finally")
    }
}

for (i in seqWithFinally) {
    println("for")
    break
}

only outputs for.

As comparisons, both the following C# code

static IEnumerable<int> YieldWithFinally()
{
    try
    {
        yield return 0;
        yield return 0;
    }
    finally
    {
        Console.WriteLine("finally");
    }
}

static void Main(string[] args)
{
    foreach (int i in YieldWithFinally())
    {
        Console.WriteLine("for");
        break;
    }
}

and the following JS code

function* yieldWithFinally() {
    try {
        yield 0
        yield 0
    } finally {
        console.log("finally")
    }
}

for (let i of yieldWithFinally()) {
    console.log("for")
    break
}

output

for
finally

For the reasons why Kotlin is designed that way, check KEEP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment