-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathIEnumerableDisposeMethodCalledWhenIterationComplete.cs
78 lines (65 loc) · 2.08 KB
/
IEnumerableDisposeMethodCalledWhenIterationComplete.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
// Demonstrates how an INumerator<T> dispose method gets called when done iterating.
//
// Based on code challenge: http://ayende.com/blog/167041/code-challenge-make-the-assertion-fire
namespace IEnumerableDisposeMethodCalledWhenIterationComplete
{
class IEnumerableDisposeMethodCalledWhenIterationComplete
{
public static IEnumerable<int> Fibonnaci(CancellationToken token)
{
yield return 0;
yield return 1;
var prev = 0;
var cur = 1;
// Finally gets called when IEnumerator<T> finishes because its Dispose method gets called.
try
{
while (token.IsCancellationRequested == false)
{
var tmp = prev + cur;
prev = cur;
cur = tmp;
yield return tmp;
}
}
finally
{
Debug.Assert(token.IsCancellationRequested);
}
}
public static void Main()
{
// Fires assert and passes.
FirstTry();
// Fires assert and fails.
SecondTry();
Console.WriteLine("\n\nPress any to exit.\n");
Console.ReadKey(true);
}
private static void SecondTry()
{
var token = new CancellationToken();
Console.WriteLine("\nSecond:");
foreach (var n in Fibonnaci(token))
{
Console.Write("{0},", n);
if (n > 10) { break; }
}
}
private static void FirstTry()
{
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
Console.WriteLine("\nFirst:");
foreach (var n in Fibonnaci(token))
{
Console.Write("{0},", n);
if (n > 10) { source.Cancel(); }
}
}
}
}