Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created May 7, 2019 02:48
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 ufcpp/ae78b9e06d77a573cd5f2fcdbefb92cd to your computer and use it in GitHub Desktop.
Save ufcpp/ae78b9e06d77a573cd5f2fcdbefb92cd to your computer and use it in GitHub Desktop.
非同期イテレーターへの 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