BT

マルチスレッドとWPF 4.5

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

原文(投稿日:2012/01/23)へのリンク

WPF 4.5ではマルチスレッド・データバインディングのサポートが改善されたが、このテクニックには依然としてリスクがある。この記事では、それがどのように動いているか、安全に使うには何が必要かについて説明する。

WPFデータバインディングはこれまでマルチスレッドを場当たり的にサポートしてきた。オブジェクトがプロパティ変更イベントを非UIスレッドで発行すると、データバインディング・インフラストラクチャが動き出す。通常これはうまくいくのだが、潜在的な競合状態のため、これは実際のところ安全ではない。コンピュータサイエンスの観点から、スレッドをまたがるアクセスを単純に許さない方が適切だろう。これは実のところコレクション変更イベントのケースだ。

残念なことに、開発者は常に正確さを気にしているわけではない。ただやりたいことをやるだけだ。その結果、「スレッドセーフ」もしくは「ディスパッチャーセーフ」なオブザーバブル・コレクションについて、さまざまな試みがなされてきた。これらの試みの基本設計はすべて、呼び出し前にコレクション変更イベントを適切なスレッドにマーシャルするというものだ。この場合、適切なスレッドとは、ディスパッチャーが実行しているいずれかのスレッドになる。残念ながら、これでは競合状態の可能性はなくならない。

MicrosoftはWPF 4.5でもっと安全な代替手段を開発者に提供している。BindingOperations.EnableCollectionSynchronizationを呼び出すことにより、WPFデータバインディングエンジンはロックを利用する。デフォルトでは、さきほどの呼び出しに指定されたオブジェクトでロックを獲得するが、もっと複雑なロックスキームを使うオプションもある。残念ながら、これは間違いやすいテクニックだ。バックグラウンドスレッドにおいて、コレクションのロックを獲得するのは忘れてしまいやすい。また、コレクションが不要になったときに、コレクション同期を無効にするのを忘れる可能性 もある。これはメモリーリークを引き起こすだろう。

このテクニックのもうひとつの問題は、個々のオブジェクトをプロテクトしないことだ。したがって、コレクションがロック下で読み出されているあいだ、コレクションに含まれるアイテムのプロパティは必ずしも安全に読み出されるわけではない。これはアトミックにできないゲッターやプロパティ(たとえば大きな値の型)の場合に問題になるだろう。

コレクションをアップデートするのにバックグラウンドスレッドを使っている人には、そのコレクションでイミュータブルオブジェクトだけを使うことを強く推奨する。あるいは、もしオブジェクトをイミュータブルにできないのなら、少なくともプロパティのゲッターをスレッドセーフにするよう、細心の注意を払うべきだ。そして、いざとなれば、この機能の存在を忘れて、コレクションのアップデートをUIスレッドにマーシャルするだけにした方がよいだろう。

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには 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