LoginSignup
7
9

More than 3 years have passed since last update.

.NETの非同期に関して ~Task, async/await(自分用メモ)

Last updated at Posted at 2016-01-22

await task が確実にスレッドプールスレッドで実行させるようにするには?

2017/01/09追記

コメントで以下のご指摘を頂きました。ご注意下さい。※但し、私の実験した環境においては確実にスレッドプールスレッドで実行されています。

await Task.Delay(1).ConfigureAwait(false); と書いても、awaitの次の行がスイッチされたコンテキストで実行されるとは限りません
本体のTaskをawaitする前に、

await Task.Delay(1).ConfigureAwait(false);

を呼び出すだけ。

Delay(1)は必ず(?)スレッドプールスレッドで実行され、そしてConfigureAwait(false)することで、UIスレッドに戻ってこないようにする、という仕組み。

背景

await した task は必ずしもスレッドプールスレッドで実行されるとは限らない。
MSDNのどこかにもそんなことが明記されていたし、実際にトータルで数秒かかる処理(IO待ち1秒+その他)が全てUIスレッドで実行されるということも頻発した。(環境依存が強そう。Windows10で頻発。)

それによって数秒間画面が固まり、その間ボタンのEnabled/Disabledも画面に反映されず… というのは、要件によっては大問題となる。
そのため、必ずスレッドプールスレッドで実行してもらう(UIスレッドを自由にさせてあげる)方法が必要となった。

以上。

ライブラリでの非同期実装について

ライブラリ内でTask.Runを使わない

スレッド、特にスレッドプールのスレッドはグローバルに共有されているリソースで、アプリケーション開発者に属しています。ライブラリの作者はTask.Runを使ったり、スレッドを作るメソッドを作成するべきではありません。どのようなタイミングでスレッドを追加するか決めるのはアプリケーション開発者の権利と責任です。

await するなら、ConfigureAwait(false) する

不用意にUIスレッドに戻らないよう。

await XxxAsync.ConfigureAwait(false)

参照

とても勉強になりました↓
.NET非同期処理(async-await)を制御する、様々な方法 – kekyoの丼
できる!C#で非同期処理(Taskとasync-await) – kekyoの丼

TAP (Task-based Asynchronous Pattern) 非同期メソッドのガイドライン
http://qiita.com/chocolamint/items/ed4999cccf011653cb78

HttpClient詳解、或いは非同期の落とし穴について
http://www.slideshare.net/neuecc/httpclient

.NETで非同期ライブラリを正しく実装する
http://www.infoq.com/jp/articles/Async-API-Design

async/await ~非同期なライブラリは楽じゃない~
http://qwerty2501.hatenablog.com/entry/2014/04/24/235849

7
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9