Skip to content

Commit 675cf37

Browse files
committed
Async enumerable sample
1 parent d595600 commit 675cf37

File tree

6 files changed

+77
-1
lines changed

6 files changed

+77
-1
lines changed

Async.Netcore.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,10 @@
66
<LangVersion>8.0</LangVersion>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<None Update="AsyncEnumerable.txt">
11+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
12+
</None>
13+
</ItemGroup>
14+
915
</Project>

AsyncDisposable.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ public async Task Run()
1010
{
1111
}
1212

13-
await using (var correct = new CorrectDisposable())
13+
await using (var correct = new CorrectDisposable()
14+
.ConfigureAwait(false))
1415
{
1516
}
1617
}

AsyncEnumerable.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Runtime.CompilerServices;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
class AsyncEnumerable : IRunnable
10+
{
11+
public async Task Run()
12+
{
13+
using var tokenSource = new CancellationTokenSource();
14+
tokenSource.CancelAfter(3200);
15+
16+
await foreach (var delay in ReadDelays()
17+
.WithCancellation(tokenSource.Token)
18+
.ConfigureAwait(false))
19+
{
20+
Console.WriteLine($"await Task.Delay({delay})");
21+
22+
await Task.Delay(delay)
23+
.ConfigureAwait(false);
24+
}
25+
}
26+
27+
async IAsyncEnumerable<int> ReadDelays([EnumeratorCancellation] CancellationToken token = default)
28+
{
29+
using (var stream = File.OpenRead("AsyncEnumerable.txt"))
30+
using (var reader = new StreamReader(stream))
31+
{
32+
string line;
33+
while ((line = await reader.ReadLineAsync()
34+
.ConfigureAwait(false)) != null)
35+
{
36+
token.ThrowIfCancellationRequested();
37+
Console.WriteLine(" Read next line");
38+
yield return Convert.ToInt32(line);
39+
}
40+
}
41+
Console.WriteLine(" Done enumerating");
42+
}
43+
}

AsyncEnumerable.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
100
2+
200
3+
400
4+
800
5+
1600
6+
3200
7+
6400

AsyncEnumerableExtensions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.IO;
2+
3+
static class AsyncEnumerableExtensions
4+
{
5+
public static void Explain(this AsyncEnumerable runnable, TextWriter writer)
6+
{
7+
writer.WriteLine(@"
8+
- `IAsyncEnumerable<T>` allows to write asynchronous pull based streams, similar to regular enumerables with `yield return` and `yield break`
9+
- `WithCancellation` only adds the token to the enumerator but doesn't influence the state machine
10+
- `WithCancellation` in combination with `[EnumeratorCancellation]` can be used to ceate a combined token
11+
");
12+
}
13+
}

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@
44
- `Stream`, `BinaryWriter`, `TextWriter` calls `.Dispose` synchronously
55
- `Stream` `FlushAsync` calls `Flush` on another thread which is bad behavior that should be overwritten
66

7+
## AsyncEnumerable
8+
9+
- `Stream`, `Utf8JsonWriter`, `System.Threading.Timer`, `CancellationTokenRegistration`, `BinaryWriter`, `TextWriter` and `IAsyncEnumerator<T>` implement `IAsyncDisposable`
10+
- `Stream`, `BinaryWriter`, `TextWriter` calls `.Dispose` synchronously
11+
- `Stream` `FlushAsync` calls `Flush` on another thread which is bad behavior that should be overwritten
12+

0 commit comments

Comments
 (0)