Skip to content

Instantly share code, notes, and snippets.

@controlflow
Created November 26, 2013 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save controlflow/7661990 to your computer and use it in GitHub Desktop.
Save controlflow/7661990 to your computer and use it in GitHub Desktop.
IX 1.2
using System;
using System.Collections.Generic;
using System.Linq;
static class Program {
static void Main() {
var xs = EnumerableEx.Create<int>(async yield => {
try {
await yield.Return(42);
} finally {
Console.WriteLine("finally");
}
});
var ys = Iterator();
// prints: "xs: 42"
foreach (var i in xs.Take(1))
Console.WriteLine("xs: {0}", i);
// prints: "xs: 42
// finally"
foreach (var i in ys.Take(1))
Console.WriteLine("ys: {0}", i);
}
private static IEnumerable<int> Iterator() {
try {
yield return 42;
} finally {
Console.WriteLine("finally");
}
}
}
@controlflow
Copy link
Author

For async methods C# compiler do not emits 'enumerator disposed early' control flow edges like in C# 2.0 iterators.
This is why any async-based anonymous iterators implementation can't correctly deal with .Take() or break; in foreach loops.

@headinthebox
Copy link

Great catch. You could use an explicit yield.Break(). Just to be very clear. This is really a hack to work around limitations in the C# language. So I am totally fine things are rough on the edges. Handle with care.

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