If I have a coroutine, will the code in the finally block be 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!"); } }
As long as the iterator / enumerator is correctly located (called IDisposable.Dispose()), then yes:
IDisposable.Dispose()
The control is always passed to the finally block no matter how the try block exits.
http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
However, be careful what is Dispose()really called, otherwise you may end up with unintended results. For more information about this phenomenon and some issues to keep in mind, check out this blog post:
Dispose()
- Dispose !
( . , , , , )
:
return yield try-catch. try, try finally.
http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx
: finally, yield return, , IDisposable.Dispose /, yield return. GetEnumerator() , MoveNext() , yield return finally, Dispose, finally . , , ( ), ( , , - ).
finally
yield return
IDisposable.Dispose
GetEnumerator()
MoveNext()
Dispose
, , vb # , foreach Dispose , , GetEnumerator(), , - Dispose(). , , , .
foreach
, , .
yield, finally , IEnumerator, . :
void Main() { var x = MyCoroutine(12); //Console.WriteLines will happen when the following //statement is executed var y = x.MoveNext(); }
Main() .., , , :
Main()
YieldReturnAndFinally
@Henk Holterman
* IEnumerable * IEnumerable<T> * IEnumerator * IEnumerator<T>