Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# yield and try-finally

If I have a coroutine as follows, will the code in the finally block get called?

public IEnumerator MyCoroutine(int input)
{
  try
  {
    if(input > 10)
    {
      Console.WriteLine("Can't count that high.");
      yield break;
    }
    Console.WriteLine("Counting:");
    for(int i = 0; i < input; i++)
    {
      Console.WriteLine(i.ToString());
      yield return null;
    }
  }
  finally
  {
    Console.WriteLine("Finally!");
  }
}
like image 279
Liron Avatar asked May 25 '11 18:05

Liron


1 Answers

As long as the iterator/enumerator is disposed properly (IDisposable.Dispose() is called) then yes:

Control is always passed to the finally block regardless of how the try block exits.

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

However, be careful that Dispose() is indeed called, or else you may end up with unintended results at best. For more information on this phenomenon and some gotchas to watch out for, check out this blog post:

Yield and usings - your Dispose may not be called!

(Thanks to Scott B for providing the link, placing in the answer since everybody seems to be missing it)

Additionally:

A yield return statement cannot be located anywhere inside a try-catch block. It can be located in a try block if the try block is followed by a finally block.

http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx

like image 157
Chris Barlow Avatar answered Sep 20 '22 13:09

Chris Barlow