6. before/after (1)
● メソッド宣言
before
string Load(string path)
after
IEnumerator Load(string path, Action<string> callback)
● 戻り値はIEnumerator固定
● 本来の戻り値はcallbackごしに返す
7. before/after (2)
● return
before
return result;
after
callback(result);
● returnステートメントの代わりにcallback呼び出し
8. before/after (3)
● 呼び出し側
before
var x = Load("path"); …(後続の処理)
after
StartCoroutine(Load("path", x => { …後続の処理 });
● 戻り値を直接受け取れない
● 形式上の戻り値(IEnumerator)はコルーチン起動のた
めに使う
● 匿名関数を使って後続の処理をつなぐ
11. Taskクラス
● こういうクラスを用意
public class Task<T> : IEnumerator
{
IEnumerator Routine;
public T Result { get; }
public Exception Error { get; }
public void OnComplete(… callback);
public Task<T> ContinueWith<U>(… continuation);
}
● 継続処理の登録
● (本来の)戻り値やエラーの伝播
13. Task利用例(戻り値)
● (本来の)戻り値の伝播
IEnumerator A(Action<int> callback);
IEnumerator B(int x, Action<string> callback);
IEnumerator C(string s);
A, B, C の順で実行したい
A の戻り値(int)を B で、B の戻り値(string)を C で使いたい
同期処理なら C(B(A()); だけで書けるもの
var t = new Task<int>(A)
.ContinueWith<string>(B)
.ContinueWith(C);
StartCoroutine(t);
14. 同期処理と比べて
● 同期処理との対比
IEnumerator A(Action<int> callback);
IEnumerator B(int x, Action<string> callback);
IEnumerator C(string s);
int A();
string B(int x);
void C(string s);
var t = new Task<int>(A) var x = A();
.ContinueWith<string>(B) var s = B(x);
.ContinueWith(C); C(s);
StartCoroutine(t); あるいは
C(B(A()));
15. Task利用例(例外処理)
● コルーチン内で発生した例外も受け取れる
var t = new Task<int>(A)
.ContinueWith<string>(B)
.ContinueWith(C)
.OnComplete(t => ● A, B, C のどこかで例外が発
{ 生した場合、そこでコルーチン
if (t.Error != null) … の実行は中断。
}); ● 発生した例外はErrorプロパ
ティにセットされる
StartCoroutine(t);