7 to this:
DateTime stop = DateTime.Now.AddSeconds(2);
foreach (int i in CountWithTimeLimit(stop))
{
Console.WriteLine ("Received {0}", i);
if (i > 3)
{
Console.WriteLine("Returning");
return;
}
Thread.Sleep(300);
}
Here we??™re not stopping early in the iterator code??”we??™re stopping early in the code
using the iterator. The output is perhaps surprising:
Received 1
Received 2
Received 3
Received 4
Returning
Stopping!
Here, code is being executed after the return statement in the foreach loop. That
doesn??™t normally happen unless there??™s a finally block involved??”and in this case
there are two! We already know about the finally block in the iterator method, but
the question is what??™s causing it to be executed. I gave a hint to this earlier on??”
foreach calls Dispose on the IEnumerator it??™s provided with, in its own finally block
(just like the using statement). When you call Dispose on an iterator created with an
iterator block before it??™s finished iterating, the state machine executes any finally
blocks that are in the scope of where the code is currently ???paused.???
We can prove very easily that it??™s the call to Dispose that triggers this by using the
iterator manually:
Executes however
the loop ends
172 CHAPTER 6 Implementing iterators the easy way
DateTime stop = DateTime.Now.AddSeconds(2);
IEnumerable
iterable = CountWithTimeLimit(stop);
IEnumerator iterator = iterable.
Pages:
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344