Silverlight 2 Beta 2におけるWebClientとHttpWebRequestの違い

Beta 2になって(前から?)この両者からコールバックされる時のスレッドに変更があったっぽい。

WebClientのDownloadStringCompletedイベントからコールバックされる時はメイン(UI)スレッドから呼び出されるのに対して、HttpWebRequestのBeginGetResponseからコールバックされる時は完全に別のスレッドから呼び出されている。

Beta 1の時はHttpWebRequestもメインスレッドからコールバックされていたはず。だってコールバックメソッドの中でUIを操作しても例外が発生していなかったからね!これがBeta 2では例外が発生するようになった。

なので、BeginGetResponseメソッドのコールバックとかでUIを操作するときはDispatcher.BeginInvoke経由で呼び出す必要がある。

Page.xaml.cs
var webReq = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://localhost/hoge"))
webReq.Method = "GET";
webReq.BeginGetResponse(r => {
   var webRes = (HttpWebResponse)webReq.EndGetResponse(r);

   this.Dispatcher.BeginInvoke(() => {
       // UIを操作する
   });
}, null);

ScottGuさんのBlogにそれらしき事が書いてあった。

Background Thread Networking

Beta2 now allows Silverlight applications to initiate network requests on background threads, as well as process/handle network responses on background threads. This enables a bunch of powerful scenarios, and allows you to avoid blocking the browser's UI thread while doing both HTTP and Socket network communication.

他にも色々なところが微妙に変わっているのでBeta 1からBeta 2へのアップグレードには結構注意が必要な感じです。