非同期イテレーターへの CancellationToken の伝搬(16.1 Preview 3)
// 16.1 Preview 3 での挙動: | |
// X1(c1) → c1 が渡る | |
// X1(c1).WithCancellation(c2) → c2 が渡る | |
// X1(c1).WithCancellation(default) → c1 が渡る | |
// X1() → default が渡る | |
// X1().WithCancellation(c2) → c2 が渡る | |
// | |
// X2() → default, default が渡る | |
// X2(c1, c2) → c1, c2 が渡る | |
// X2(c1, c2).WithCancellation(default) → c1, c2 が渡る | |
// X2(c1, c2).WithCancellation(c3) → c3, c3 が渡る | |
// | |
// 今後変更されそうな点: | |
// 複数の引数に EnumeratorCancellation 属性を付けちゃダメ (今の X2 はコンパイル エラー) | |
// X1(c1).WithCancellation(c2) の時、 CancellationTokenSource.CreateLinkedTokenSource(c1, c2) が渡りそう | |
using System; | |
using System.Collections.Generic; | |
using System.Runtime.CompilerServices; | |
using System.Threading; | |
using System.Threading.Tasks; | |
class Program | |
{ | |
static Dictionary<int, string> _nameTable = new Dictionary<int, string>(); | |
static async Task Main() | |
{ | |
var c1 = new CancellationTokenSource(); | |
var c2 = new CancellationTokenSource(); | |
var c3 = new CancellationTokenSource(); | |
_nameTable = new Dictionary<int, string> | |
{ | |
{ c1.GetHashCode(), "c1" }, | |
{ c2.GetHashCode(), "c2" }, | |
{ c3.GetHashCode(), "c3" }, | |
{ default(CancellationToken).GetHashCode(), "default" }, | |
}; | |
Console.WriteLine("-- X1() --"); | |
await foreach (var x in X1()) ; | |
Console.WriteLine("-- X1(c1) --"); | |
await foreach (var x in X1(c1.Token)) ; | |
Console.WriteLine("-- X1().With(c2) --"); | |
await foreach (var x in X1().WithCancellation(c2.Token)) ; | |
Console.WriteLine("-- X1(c1).With(default) --"); | |
await foreach (var x in X1(c1.Token).WithCancellation(default)) ; | |
Console.WriteLine("-- X1(c1).With(c2) --"); | |
await foreach (var x in X1(c1.Token).WithCancellation(c2.Token)) ; | |
Console.WriteLine("-- X2() --"); | |
await foreach (var x in X2()) ; | |
Console.WriteLine("-- X2(c1, c2) --"); | |
await foreach (var x in X2(c1.Token, c2.Token)) ; | |
Console.WriteLine("-- X2().With(c3) --"); | |
await foreach (var x in X2().WithCancellation(c3.Token)) ; | |
Console.WriteLine("-- X2(default, c2).With(c3) --"); | |
await foreach (var x in X2(default, c2.Token).WithCancellation(c3.Token)) ; | |
Console.WriteLine("-- X2(c1, default).With(c3) --"); | |
await foreach (var x in X2(c1.Token, default).WithCancellation(c3.Token)) ; | |
Console.WriteLine("-- X2(c1, c2).With(default) --"); | |
await foreach (var x in X2(c1.Token, c2.Token).WithCancellation(default)) ; | |
Console.WriteLine("-- X2(c1, c2).With(c3) --"); | |
await foreach (var x in X2(c1.Token, c2.Token).WithCancellation(c3.Token)) ; | |
} | |
static async IAsyncEnumerable<int> X1([EnumeratorCancellation]CancellationToken ct = default) | |
{ | |
Console.WriteLine($"X {_nameTable[ct.GetHashCode()]}"); | |
await Task.Yield(); | |
yield break; | |
} | |
static async IAsyncEnumerable<int> X2([EnumeratorCancellation]CancellationToken ct1 = default, [EnumeratorCancellation]CancellationToken ct2 = default) | |
{ | |
Console.WriteLine($"X2 {_nameTable[ct1.GetHashCode()]} {_nameTable[ct2.GetHashCode()]}"); | |
await Task.Yield(); | |
yield break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment