SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Silverlight 2でのコンテンツの非同期ダウンロード

ダウンロードしたコンテンツの読み込み(3)

アプリケーションモジュールの読み込み

 アプリケーションは、複数のモジュールに分割する方が管理しやすくなります。こうしたモジュールはクラスライブラリとして取りまとめ、アプリケーションの.xapファイルにパッケージ化することもあります。クラスライブラリを.xapファイルに追加すると、他の.NETプロジェクトと同様に参照できます。しかしその場合、.xapファイルのサイズが大きくなってしまい、ユーザーに無駄な待ち時間を強いることになりかねません。幸い、これをスマートに解決する方法があります。

 Silverlightでは、モジュールをオンデマンドでダウンロードする柔軟なアプリケーションを作成できます。そのためには、まずはクラスライブラリを通常どおり作成します。しかし、Silverlightアプリケーションからそのライブラリを参照するのではなく、リモートサーバにアップロードしておき、WebClientクラスを使ってダウンロードする形にします。そして、ダウンロードしたライブラリはリフレクションにより利用します。コード9はその例です。

コード9
private void RequestContent()
{
Uri address =
new Uri("http://www.somedomain.com/MyClassLibrary.dll");

WebClient webClient = new WebClient();
webClient.OpenReadCompleted += new
OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(address); (1)
}

void webClient_OpenReadCompleted(object sender,
OpenReadCompletedEventArgs e)
{
AssemblyPart assemblyPart = new AssemblyPart(); (2)
Assembly assembly = assemblyPart.Load(e.Result); (3)

object myClass =
assembly.CreateInstance("MyClassLibrary.MyClass"); (4)
object result = myClass.GetType().InvokeMember( (4)
"GetCurrentTime", BindingFlags.InvokeMethod, null,
myClass, null); (4)
myTextBlock.Text = Convert.ToString(result); (4)
}

 このコードは、アプリケーションモジュールを動的にダウンロードして使用する例です。アプリケーションモジュールはバイナリファイルの一種ですので、おなじみのOpenReadAsyncでダウンロードできます(1)。このメソッドが完了すると、ダウンロードしたStreamを使ってクラスライブラリにアクセスできます。しかし、クラスライブラリの中身を利用するためには、まずはAssemblyに変換する必要があります。

 Assemblyはコンポーネントのメモリ内表現ですので、AssemblyPartクラスのインスタンスを通じてメモリに読み込むことができます(2)。このクラスは、アプリケーションのパッケージ(.xapファイル)に含めるアセンブリを表します。アセンブリを含めるには、ダウンロードしたStreamAssemblyPartオブジェクトのLoadメソッドに渡します(3)。このメソッドにより、現在のアプリケーションドメインに新しいクラスライブラリが追加されます。

 Assemblyをアプリケーションドメインに読み込んだら、その中身を利用できます。例えば、クラス、列挙型、構造体などです。さらに、こうした項目がメソッド、プロパティ、イベントなどのメンバを持つ場合、リフレクションを通じてこうしたメンバを呼び出すことができます。コードの(4)の部分がその例です。リフレクションは.NET Frameworkの基本機能であり、この記事では詳しく取り上げません。.NET Framework関連の書籍を見れば必ず説明があるはずです。ともあれ、オンデマンドでダウンロードしたクラスライブラリの中身を利用するためにはリフレクションを用いるということだけ頭に入れておいてください。さて、時として、ファイルをオンデマンドでダウンロードする処理がうまくいかないことがあります。例えば、要求が何らかの理由で中断された場合などです。次に、こうした状況への対処方法を見てみましょう。

要求処理の中断への対処

 オンデマンドのダウンロード要求は、意図的に中断する場合と、予期せず中断する場合とがあります。意図的な中断は、ユーザーが非同期の要求をキャンセルした場合に発生します。キャンセルの処理方法については別のセクションで既に説明しました。また、不測の事態が発生してダウンロード要求がエラーになる場合もあります。いずれにせよ、ダウンロードしたコンテンツを利用する前に、ダウンロードが正常に完了したかどうかを確認する処理をきちんと組み込んでおくことが必要です。コード10はその例です。

コード10
void webClient_OpenReadCompleted(object sender,
OpenReadCompletedEventArgs e) (1)
{
if ((e.Cancelled == false) && (e.Error == null)) (2)
{
myTextBlock.Text = "Download Succeeded!";
}
}

 このコードは、ダウンロードが成功したかどうかをチェックする方法の例です。このコードは、OpenReadAsyncメソッドで開始した要求に対して動作し、判別はOpenReadCompletedEventArgs型のパラメータで行います。また、DownloadStringAsyncメソッドで開始した要求の場合も、対処方法は同じです。DownloadStringCompletedEventArgsOpenReadCompletedEventArgsも、同じAsyncCompletedEventArgsから派生しているからです。上記のコードで利用しているCancelledErrorの2つは、いずれもこの派生元が公開しているプロパティです(2)。

 Cancelledプロパティはbool型で、ダウンロード要求が中止されたかどうかを示します。中止の場合はtrue、それ以外の場合はfalseです。また、エラーが発生した場合には、Cancelledプロパティはfalseになります。その場合は、問題の詳細を示すExceptionErrorプロパティに入っています。処理が成功だった場合には、コード10からも分かるように、Cancelledプロパティはfalseになり、Errorプロパティはnullになります。

まとめ

 アプリケーションモジュールを必要に応じてダウンロードできるようにしておくと、最初の読み込みに必要な時間が短くなり、ユーザーの操作感が向上します。この強力な追加機能は、フォント、メディア、テキストの各コンテンツの取得などでも生かせます。また、複数の要素を取りまとめた圧縮ファイルをダウンロードすることもできます。いずれにせよ、実行時にコンテンツをオンデマンドでダウンロードできるのは、利用価値の高い機能です。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

chad.campbell(chad.campbell)

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3558 2009/03/03 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー