去年書いたやつがクソすぎたのでけっこう後悔していたんだけど、今日気がついたやりかた。
@laughterさんが修正してくれた改良前のコード
static class TaskExtention {
//返り値なし
public static void NoWait(this Task task, Action<Task> action = null, CancellationToken? ct = null)
{
if (action != null) {
if (ct != null) {
task.ContinueWith(action, (CancellationToken)ct).ConfigureAwait(false);
} else {
task.ContinueWith(action).ConfigureAwait(false);
}
} else {
if (ct != null) {
task.ContinueWith(_ => {}, (CancellationToken)ct).ConfigureAwait(false);
} else {
task.ContinueWith(_ => {}).ConfigureAwait(false);
}
}
}
//返り値あり
public static void NoWait<TResult>(this Task<TResult> task, Action<Task<TResult>> action = null, CancellationToken? ct = null)
{
if (action != null) {
if (ct != null) {
task.ContinueWith(action, (CancellationToken)ct).ConfigureAwait(false);
} else {
task.ContinueWith(action).ConfigureAwait(false);
}
} else {
if (ct != null) {
task.ContinueWith(_ => {}, (CancellationToken)ct).ConfigureAwait(false);
} else {
task.ContinueWith(_ => {}).ConfigureAwait(false);
}
}
}
}
改良版
@laughter さんの修正案コメント
??とCancellationToken.Noneを使うとキャストを消せる
を見て「パラメータ省略時の値にCancellationToken.None」を指定できたらもっとすっきりするのになー」と思ってたら、default(CancellationToken)と書くことで可能 アンド task.ContinueWith(action, CancellationToken.None)
はtask.ContinueWith(action)
と同等との記述を見つけたのでさらに改良。
ついでにactionの方の扱いも修正して、if文のネストがごっそりなくなりました。
static class TaskExtention
{
//返り値なし
public static void NoWait(this Task task, Action<Task> action = null, CancellationToken ct = default)
{
task.ContinueWith(action ?? (_ => { }), ct).ConfigureAwait(false);
}
//返り値あり
public static void NoWait<TResult>(this Task<TResult> task, Action<Task<TResult>> action = null, CancellationToken ct = default)
{
task.ContinueWith(action ?? (_ => { }), ct).ConfigureAwait(false);
}
}
使い方
使い方
void NoAsyncMethod(CancellationToken ct)
{
//返り値なし、後処理なし
AsyncMethod().NoWait();
//返り値あり、後処理あり、CancellationTokenあり
AsyncMethodWithResult(ct).NoWait(task => { var result = task.Result; }, ct);
}
呼び出し側で実行結果を受け取ることはできない。
「呼び出したいメソッドがasyncなやつしかないけど、呼ぶ側はasyncにできない。処理完了を待ったり結果を受け取る必要はなくて投げっぱなしでOK」といったケース用のお手軽メソッドなので、そういう制約を気にする必要がないときに使うものです。