イテレーター
• 中断と再開
class MethodEnumerator: IEnumerator<int>
{
public int Current { get; private set; }
private int _state = 0;
public bool MoveNext()
{
switch (_state)
{
case 0:
IEnumerable<int> Method()
{
yield return 1;
Current = 1;
_state = 1;
return true;
case 1:
Current = 2;
_state = 2;
return true;
case 2:
yield return 2;
}
}
}
}
default:
return false;
35.
イテレーター
• 中断と再開
class MethodEnumerator: IEnumerator<int>
{
public int Current { get; private set; }
private int _state = 0;
public bool MoveNext()
{
switch (_state)
{
case 0:
状態の記録
Current = 1;
Current = 1;
_state = 1;
_state = 1;
return true;
中断
return 1:
case true;
case 1: = 2;
Current
_state = 2;
return true; 再開用のラベル
IEnumerable<int> Method()
{
yield return 1;
yield return 2;
case 2:
}
}
}
}
default:
return false;
36.
awaitの展開結果(コンセプ
ト)
• コンセプト的には イテレーター+
ContinueWith
状態の記録
async Task<int> Method()
{
var x = await task1;
var y = await task2;
}
_state = 1;
if (!task1.IsCompleted)
{
task1.ContinueWith(a);
return;
中断
}
再開用のラベル
case 1:
var x = task1.Result;
結果の受け取り
37.
awaitの展開結果
• 実際はもう少し複雑
• Awaiterというものを介していたり(Awaitableパ
_state= 1;
ターン)
var awaiter1 = task1.GetAwaiter();
if (!awaiter1.IsCompleted)
{
awaiter1.OnCompleted(a); •
return;
}
•
case 1:
var x = awaiter1.GetResult();
こいつが同期コンテキスト
を拾い上げていたりする
Awaiterを自作することで、
awaitの挙動を変更可能
• Task以外もawait可能