BT

.NET 4.5のTask Parallel Libraryに関する変更とアドバイス

| 作者: Jonathan Allen フォローする 593 人のフォロワー , 翻訳者 笹井 崇司 フォローする 0 人のフォロワー 投稿日 2012年3月30日. 推定読書時間: 3 分 |

原文(投稿日:2012/03/27)へのリンク

.NET 4.0以下において、TaskクラスはIDisposableインターフェイスを公開している。これは、IAsyncResultインターフェイスのAsyncWaitHandleプロパティによって公開されているwaitハンドルをクリーンナップするためだ。.NET 4.0において、このwaitハンドルはAsyncWaitHandleプロパティが読み出されたり、Task.WaitAllもしくはTask.WaitAnyが使われたときにだけ作られる。それ以外では、Task.Disposeを呼び出す必要はない。

残念なことに.NET 4.0では、Taskクラスは過度に例外ObjectDisposedExceptionを投げる。Disposeを呼び出すと、たとえリリースされたwaitハンドルを使うプロパティがなくても、オブジェクト全体が使えなくなるのだ。

.NET 4.0ではTask.Disposeを呼び出すべきだろうか?

答えはノーだ。ただし、以下が当てはあまらない限りはだ。

  1. 完了したTaskはキャッシュされない。
  2. waitがTask.WaitAllかTask.WaitAnyの呼び出し、もしくはIAsyncResult.AsyncWaitHandleの読み出しにより作られた。
  3. 対象となるTaskを保持するタスクやスレッドが他にない。

たとえこれらの要件がすべて当てはまったとしても、ファイナライザが適当にwaitハンドルのクリーンナップを効率よくやってくれるように見えるかもしれない。したがって、パフォーマンスに問題がない限りは、タスクを解放しないでいられるだろう。

.NET 4.5 Coreの変更

.NET 4.5では、内部のwaitハンドルは明示的にIAsyncResult.AsyncWaitHandleプロパティを読み出したときのみ作られるようになった。それ以外では、Task.WaitAllやTask.WaitAnyを含めて、それが不要なよう再設計されたのだ。そして、async/awaitのための言語サポートが追加されたことにより、多くのシナリオではIAsyncResultももはや不要だ。

.NET 4.5のTaskにおけるもうひとつの変更は、解放した後も利用できることだ。Stephen Toub氏によると、「Taskを解放した後もその公開メンバーはすべて使えるようになっており、解放前と同じように動きます。使えない唯一のメンバーはIAsyncResult.AsyncWaitHandleです。なぜなら、それがTaskインスタンスを解放するときに実際に解放されるものだからです。Taskが解放された後、そのプロパティを使おうとすると、ObjectDisposedExceptionが投げられます。」

したがって.NET 4.5においては、Task.Disposeを呼び出す方が安全ではあるが、それを必要とする理由はほとんどない。

.NET 4.5 Metroの特別ルール

続けてStephen Toub氏は、「Metroスタイルアプリのための.Net」プロファイルを使っているなら、Task.Disposeは存在すらしない、と言う。Taskに関するWinRTドキュメントはまだこの設計変更が反映されていない。

関数からのTask/Task<T>の戻り

同期メソッドの非同期ラッパーを公開すべきか?」という別の記事で、Stephen氏は関数からのTaskオブジェクトのリターンについて詳しく説明している。この記事を全部読むことをお勧めするが、急いでいる人のために、簡単に紹介する。

公開されるべき非同期メソッドは、同期メソッドよりもスケーラビリティにおいてメリットのあるものだけにすべきだと私は考えています。非同期メソッドは純粋に解放のために公開されるべきではありません。それは、特に同期メソッドを非同期にするようにした機能を使うことで、同期メソッドの消費者が簡単に実現できることなのです。

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

あなたの意見をお聞かせください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする
コミュニティコメント

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

ディスカッション

InfoQにログインし新機能を利用する


パスワードを忘れた方はこちらへ

Follow

お気に入りのトピックや著者をフォローする

業界やサイト内で一番重要な見出しを閲覧する

Like

より多いシグナル、より少ないノイズ

お気に入りのトピックと著者を選択して自分のフィードを作る

Notifications

最新情報をすぐ手に入れるようにしよう

通知設定をして、お気に入りコンテンツを見逃さないようにしよう!

BT