.NETでXML WebサービスのXmlSerializersアセンブリを事前生成する

動的XmlSerializersアセンブリ生成のオーバヘッドを無くしちゃおっていうお話です。。。


スマートクライアントで、画面の初回表示だけ遅いという事はないでしょうか?

初回だけといえば初回だけなのですが、今回はそこを何とかしてみたいと思います。

画面の初回表示が遅い理由

Windows フォーム アプリケーションなどの Webサービス クライアント クラス(Web Reference)は、初回Newの際に動的にXmlSerializersアセンブリが生成されます。

これは結構ハイコストです。


とある環境では、1コあたり200〜300msを要していました。*1

Formのコンストラクタで10コくらいNewしていたりすると涙目です。*2



アプリ起動時、バックグラウンドでリフレクション使って全部Newするなんてドロ臭いことやってる人もいるかもしれません。(やり掛けたし;)


でも、動的にできる事は静的に出来ないワケがないjk!って事で真面目に調べてみるとあるじゃぁないっスか!

XMLリアライザー ジェネレーターは、指定された型のオブジェクトをシリアル化または逆シリアル化するとき、XmlSerializer の起動パフォーマンスを向上させるために、指定されたアセンブリの型に対して XML シリアル化アセンブリを作成します。

"/p"オプション

XML Web サービス プロキシ型に対してのみシリアル化コードを生成します。
使えそうです。


解説抜粋

XMLリアライザー ジェネレーターは、サーバーとの通信に XML Web サービス プロキシを使用するクライアントのパフォーマンスも向上させますが、これは型が初めて読み込まれるとき、シリアル化プロセスによってパフォーマンスが低下しないためです。
ビンゴっぽいw


基本的な使い方

sgen.exeは、VS2010の標準インストールでは、C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin にあります。

"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\sgen.exe" /p [アセンブリ名].exe

を実行すると、同じフォルダに[アセンブリ名].XmlSerializers.dll が出力されます。

同じフォルダに置いておけばおkです。


応用

PostBuildEventに組み込みましょう。

"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\sgen.exe" /f /p "$(TargetPath)"

これでビルドの都度sgen.exeが実行されます。



Work! Enjoy it!

*1:VSのプロファイラにて計測。

*2:そもそも、Webサービスをローカルの共通関数的に考えている今の間違ったアーキテクチャの方がどうかと思うけど。