Silverlight 2 β2 で、WebHttpRequest や WebClient が、本当に非同期通信になりました。
うん。なんかね、「非同期通信にしか対応していないよ」と書いてあったのに、Silverlight 上ではスレッドが1つしかなかったのね。それが、UI Thread と、Communication Thread に分かれたの。
はい、何が起こるかわかるよね。Communication Thread で UI Elements を操作しようとすると、例外が発生しますorz...
それと、Uri 型だった WebClient.BaseAddress が、ただの文字列になりましたorz...
そんなわけで、第3回と、第4回のコードを書き直し。
まず、SyncronizationContect を用意します。その名の通り、同期するためのコンテキストです。こいつに、UI Thread を参照させます。そして、通信を受け取った後、UI Thread で通信の内容を転写します。
元ネタは、開発者さんのブログ。
では、書き直したコード。
// 同期コンテキスト
SynchronizationContext syncContext;
public Page() {
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e) {
    // 現在のコンテキストを参照させておく
    syncContext = SynchronizationContext.Current;
    WebClient client = new WebClient();
    // ただの文字列なので、Uri に変換
    Uri assmblUri = new Uri(client.BaseAddress);
    // β1ではパスだったのに、.xap に変わっているので、パスに変換
    string path = System.IO.Path.GetDirectoryName(assmblUri.LocalPath).Replace('\\', '/');
    // スキーマやホストをつなげて URI にできる文字列にする
    string uri = String.Format("{0}://{1}{2}/warnigLog.xml"
        , assmblUri.Scheme, assmblUri.Host, path, assmblUri.AbsolutePath);
    textBox1.Text = uri;
    Uri logUri = new Uri(uri);
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(logUri);
    request.BeginGetResponse(new AsyncCallback(GetWarningLog), request);
}
private void GetWarningLog(IAsyncResult result) {
    HttpWebRequest request = (HttpWebRequest)result.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
    // 同期コンテキストから呼び出す
    syncContext.Post(SynchronizedResponse, response);
}
private void SynchronizedResponse(object state) {
    HttpWebResponse response = state as HttpWebResponse;
    Stream stream = response.GetResponseStream();
    try {
        XmlSerializer serializer = new XmlSerializer(typeof(WarningLog));
        log = (WarningLog)serializer.Deserialize(stream);
        textBox1.Text += ":resieved\n";
        foreach (Warning w in log.WarningList) {
            textBox1.Text += (w.ToString() + "\n");
        }
    } catch (Exception ex) {
        textBox1.Text = ex.ToString();
    }
}
	
		投稿日時 : 2008年6月12日 21:39