tmytのらくがき

個人の日記レベルです

await Task.Delay(long) はCPU実行時間に含まれない

ストアアプリのBackground TaskはCPUクオータが設定されていて、 クオータは通常1秒です。このクオータは一度使い切ると次回タスクが実行されるまで 補充されません。*1

さて、ここのクオータはMSDNによると"実際にユーザコードが実行された時間"だそうです。 なんのこっちゃさっぱりわかりませんが、なにがクオータの対象になるかというと

var n = 100; // 対象
n += 10; // 対象

var sr = new StreamReader(stream); // 対象
await Task.Delay(100); // 実際にCPUを解放した時間は対象外

ということなのです。つまり、awaitでWinRT APIを待機している間はクオータに含まれないのです。

ということは、15分に1回で1秒しかBackgroundTaskは実行できませんが、Task.Delayで CPUを解放している間はクオータに含まれないので1回の処理が66msに収まるのであれば次のコードで 1分おきにBackgroundTaskを実行することもできます。

for(var i = 0; i < 15; ++i){
    await Tasks.Delay(59940); // とりあえず59930ms
}

ということで、この仕組みをつかってライブタイルに情報を出すとあるアプリを作ってみたのですが 見事Rejectされました。 ちなみにReject理由はライブタイルではないのでRejectと本稿に関連性はありません。

*1:MSDNに書いてます。