Posts

Showing posts from 2009

特定のクラスやメンバーだけ FxCop のメッセージを抑制したい

Image
FxCop を使っていると、特定のクラスやメンバーだけ警告を出さないようにしたい時がある。そんな時は警告を抑制したい対象に System.Diagnostics.CodeAnalysis 名前空間で定義されている SuppressMessage 属性をつければよい。例えば [SuppressMessage("Microsoft.Usage", "CA1801")] public static void SetValue(string value){}   これだけだと警告が抑制されないので、もう一仕事必要。 分析対象プロジェクトのプロパティ設定画面を開いて、条件付きコンパイルシンボルに CODE_ANALYSIS を追加する。

Ruby 技術者認定試験に合格

こちら へ移動。

MySQL から SELECT してきた文字列を UTF-8 にする (for Ruby 1.9 + Rails 2.3.3)

こちら へ移動。

Rails 2.3.3 で日本語を含むテンプレートをレンダリングできない問題を解決する

こちら へ移動。

Ruby ではコアなクラスが C で実装されている

こちら へ移動。

LOH (ラージオブジェクトヒープ) でフラグメンテーションが起こる !?

Image
元ネタは こちら 。   CLR のガベージコレクタはメモリを G0、G1、G2 (G は generation の G)、LOH (ラージオブジェクトヒープ) 4つの領域に分けて管理する。G0、G1、G2は 85KB 以下のオブジェクト用、LOH は 85KB よりも大きいオブジェクト用という位置づけである。この LOH がある条件を満たすとフラグメンテーションを起こし、多くのメモリが空いているのに使えない状態になってしまう。   CLR が LOH に対してガベージコレクションを欠ける際、参照されていないオブジェクトのメモリ領域を開放するだけで、コンパクション (空いたメモリ領域を詰める処理) を行わない。大きなオブジェクトを移動するのはコストがかかるため、あえてしうないように実装しているらしい。また、CLR は新しいオブジェクトのメモリ領域を確保する際、開き領域を探す手間を軽減するため、前回確保した領域のすぐ後に確保しようとする。 CLR がこのような挙動をするため、寿命が長い大きめ (ぎりぎり LOH に入る程度) のオブジェクトと寿命の短い巨大 (数 MB とかそれ以上) オブジェクトを交互に生成し、かつ巨大オブジェクトのサイズが少しずつ大きくなるような場合に、下の図のように大量のフラグメンテーションが発生してしまう。 こんな状況に陥るのはまれだが、障害解析のための知識の1つとして LOH では大量のフラグメンテーションが起こる可能性がある、ということを頭に入れておくとよいだろう。

Windows Forms 入力検証 - Disable にした TextBox の入力検証を抑制する

Image
ボタンクリック時の入力検証などにしようする Form.ValidateChildren()。 Form 内の全コントロールの検証を行うメソッドなのだが、時に検証して欲しくないコントロールまで検証を実行してしまう。例えば、ラジオボタンによってテキストボックスの一部が Disable になったりする場合、ValidateChildren() を呼ぶと Disable のテキストボックスの検証も走ってしまう。 この動作は、ValidationConstraints 型の引数をとる ValidateChildren() のオーバーロードメソッドで制御することが可能。Disable のテキストボックスの入力検証を行わない場合は ValidateChildren(ValidationConstraints.Enabled) とする。個別のコントロールのプロパティや Validating イベントハンドラでは特に何もする必要がない。

Windows Forms 入力検証 - エラー項目のフォーカスをロックしないパターン

Image
今回は、コントロールに入力エラーがある場合もフォーカスをはずせるように実装するパターン。 要件 前回と同じくこういう画面を考える。 この画面を作る上で、このような要求があるとする。 TextBox に必須入力チェックを実装する。ただし、エラーがある場合も TextBox からフォーカスがはずせるようにする。 Register ボタンをクリックした際、画面の全項目の入力チェックを実施し、エラーがあった場合は処理を中止する。 TextBox に入力エラーがある状態でも、閉じるボタン (タイトルバー右の) が機能する。 実装 以下のようにプロパティとイベントの設定を行う。 Form の設定 入力エラー時にもフォーカスをはずせるように実装する場合、ポイントは Form の AutoValidate プロパティです。このプロパティの値を EnableAllowFocusChange に変更すれば、入力エラーがあっても、フォーカスがはずれるようになります。 ただし、AutoValidate を変更しても、入力エラーがあるコントロールにフォーカスが当たっている状態でタイトルバーの閉じるボタンを押した場合、自動的に Close をキャンセルされてしまいます。これを回避するためには、OnFormClosing() をオーバーライドして、e.Cancel = false にします。 protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); e.Cancel = false; } TextBox の設定 TextBox の入力検証を行う処理を実装する。Validatingイベントハンドラの実装は、フォーカスをはずせなくする場合とまったく同じで、入力エラーがある場合には e.Cancel = true を設定する。ただし、Form の設定により、e.Cancel に true を設定してもフォーカスははずれる。 private void ValidateTextBoxIsNotEmpty(object sender, CancelEventArgs e) { TextBox t

Windows Forms 入力検証 - エラー項目のフォーカスをロックするパターン

Image
これまでの経験上、画面の単項目入力検証のコードは汚くなりがちなところの1つだ。Windows Forms が提供している機能に対する知識不足のせいで、どうしても無理やり仕様を満たすためのトリッキーなコードを書いてしまうことが多い。そんなことをしているので、後々の障害対応や仕様変更のときにイヤな思いをするはめに... そこで、Windows Forms の入力検証について、要件毎に実装パターンをまとめようと思う。まずは、入力エラーがあるコントロールからフォーカスをはずせないように実装するパターン。 要件 こんな画面を考える。 この画面を作る上で、このような要求があるとする。できるだけコードが汚くならないように、この画面を実装したい。 TextBox に必須入力チェックを実装し、エラーがあった場合は TextBox からフォーカスがはずれないようにする。 Register ボタンをクリックした際、画面の全項目の入力チェックを実施し、エラーがあった場合は処理を中止する。 TextBox に入力エラーがある状態でも、Cancel ボタンと閉じるボタン (タイトルバー右の) はクリックできる。 実装 以下のようにプロパティとイベントの設定を行う。 TextBox の設定 TextBox の入力検証を行う処理を実装する。入力エラーがある場合、e.Cancel に true を設定することで、フォーカスがはずれなくなる。 private void ValidateTextBoxIsNotEmpty(object sender, CancelEventArgs e) { TextBox textBox = (TextBox)sender; if (String.IsNullOrEmpty(textBox.Text)) { this.errorProvider1.SetError(textBox, "This text box must have value."); e.Cancel = true; } else { this.errorProvider1.SetError(textBox, St

strfriend で正規表現を可視化する

Image
他人が書いた正規表現を解読するのは大変な作業だが、そんな苦痛を少しだけやわらげてくれるオンラインサービス、 strfriend なんていうものがある。 正規表現を入力すると、そのパターンを図示してくれる。

Google AJAX API チームの Google Chrome Frame 検出 API

Google AJAX API チームのブログ で、Google Chrome Frame 検出用 API を作成中、とアナウンスされていた。 Google AJAX APIs Blog: Google Chrome Frame Ajax Detection Google Chrome Frame がインストールされているかどうかを確認できるので、されていなければインストールを促す、あるいは Google Chrome Frame の有無によって細かい制御を行うといったことが可能になります。 シンプルデモページ で使用例を見ることができる。   Web アプリケーションを作る側からすると、テストケースが増えるので Google Chrome Frame に対して諸手を挙げて大賛成できないのだが、あの IE で HTML5 やハイパフォーマンスの JavaScript エンジンを使えるようになるのは、ユーザーとしてはありがたい。 大手のサイトが対応し始めて、雑誌か何かで「Google Chrome Frame で IE を早くする」みたいな特集が組まれたら、一気に Google Chrome Frame 人口が増えそうだ。IE は使い慣れてるから別のものにはしたくないんだけど遅くて... と思っている人は多いはず。

Web.config Security Analyzer 使ってみた

Image
Web.config の脆弱性を検出するツール Web.config Security Analyzer (wcsa) の GUI 版を使ってみた。web.config を読み込ませると、こんなレポートが出てくる。   脆弱性検証ルール 今のところこんなルールが定義されている。 デバッグが無効になっているか Form 認証のパスワードが暗号化されているか カスタムエラーが有効になっているか クッキーレス認証が無効になっているか 認証クッキーを SSL で送信するようになっているか 認証クッキーがユニークになるように考慮しているか スライド式有効期限が無効になっているか クッキーパスに制限を加えているか (‘/’ 以外を設定しているか) 別の Web アプリケーションへのリダイレクトが無効になっているか 暗号化されていないクッキーを拒否しているか 検証されていないクッキーを拒否しているか クライアントのスクリプトからクッキーへのアクセスが無効になっているか ViewState が有効になっているか ViewState のメッセージ認証チェックが有効になっているか ViewState が暗号化されているか リクエストの検証が有効になっているか RoleManager が管理するクッキーを SSL で送信するようになっているか RoleManager が管理するクッキーのスライド式有効期限が無効になっているか RoleManager が管理するクッキーの暗号化が有効になっているか RoleManager が管理するクッキーの検証が有効になっているか RoleManager が管理するクッキーパスに制限を加えているか クッキーレスセッションが無効になっているか トレースが無効になっているか コードアクセスセキュリティレベルが Minimal になっているか Web.config にユーザー情報が定義されていないか   検証ルールとその適用方法 ルールは全て外部 XML ファイルとして定義されており、このファイルに どの要素の

WebsiteSpark : Web アプリ開発に必要なソフトウェアが 3 年無料に

Scott Guthrie 氏のブログ で WebsiteSpark のローンチがアナウンスされた。Web アプリケーションの開発をやっている小さな企業を補助するためのプログラムで、開発に必要な下記のソフトウェアを 3 年間無料で使えるとのこと (プログラム参加手数料が 100 ドルかかる)。 Visual Studio 2008 Professional を 3 ライセンス Expression Studio 3 (Expression Blend、Sketchflow、Web を含む) を 1 ライセンス Expression Web 3 を 2 ライセンス Windows Web Server 2008 R2 を 4 プロセッサライセンス SQL Server 2008 Web Edition を 4 プロセッサライセンス DotNetPanel コントロールパネル ちなみに Windows Server と SQL Server のライセンスは開発もデプロイも可能。3 年たった後は、使うのをやめても良いし、年間 999 ドルパッケージでこれらのソフトウェアを購入しても良いし、プロダクションサーバーライセンスだけ年間 199 ドルで買っても良いそうだ。 プログラムへの参加資格はこの2つの条件を満たしていること。 自社以外のために Web サイトや Web アプリケーションを作っている 社員数が 10 人未満

wcsa : web.config のセキュリティチェックツール

Google Code で wcsa (web.config security analyzer) というプロジェクトを見つけた。 名前の通り、web.config の脆弱性分析ツールで、30 以上のセキュリティチェック機能、詳細レポートの生成機能があるようだ。実行には .NET 3.5 が必要とのこと。 使ってみたらどんな感じか報告しようと思う。

Google Chrome Frame がリリースされた

Chromium Blog より 。 サマリーのところで Google Chrome Frame は「IE に HTML5 やオープンウェブテクノロジーをもたらすプラグイン」だと説明されている。HTML5 の canvas タグのサポートや JavaScript のパフォーマンス改善などの恩恵が得られる。 Google Chrome Frame をインストール後、 <meta http-equiv="X-UA-Compatible" content="chrome=1"> がついた Web ページを開くと Google Chrome Frame が起動して、WebKit ベースのレンダリングエンジンがページのレンダリングをする。Google Chrome Frame 対応のページを表示すると、皮だけ IE で中身は WebKit ということになるようだ。

.NET 4 BCL の新機能 (4) : メモリマップドファイル

メモリマップドファイルは、巨大なファイルの編集や、プロセス間通信のための共有メモリの作成を可能にする新機能。プロセスのアドレス空間をファイルにマップし、その後はメモリを読み書きしたり、ファイルのコンテンツを編集したりできる。ファイルは OS のメモリ管理機構を通じてアクセスされるので、自動的に多くのページに分割される (必要に応じてページイン/ページアウトされる)。開発者自身でメモリを管理する必要がなくなるので、巨大なファイルを簡単に扱えるようになるし、ファイルに完全にランダムアクセスできるようにもなる。 メモリマップドファイルを使うためには、MemoryMappedFile クラスの以下のメソッドで MemoryMappedFile クラスのインスタンスを作る (このクラスは System.IO.MemoryMappedFiles 名前空間にある)。 CreateFromFile CreateNew CreateOrOpen OpenExisting インスタンスを生成したら、CreateViewStream メソッドや CreateViewAccessor メソッドで、実際にファイルとアドレス空間をマップするためのビューを作る。CreateViewStream メソッドではシーケンシャルアクセス用の Stream が得られる (.NET の一般的な Stream と同じように使用可能)。CreateViewAccessor はランダムアクセスが可能な MemoryMappedFileViewAccessor クラスのインスタンスを返す。   サンプルコード メモリマップドファイルを使ったプロセス間通信のサンプル。まず下のコードで mymappedfile という名前をつけたメモリマップドファイルを作成し、”Hello World!” を書き込んだ後、別プロセスを立ち上げている。 using (varmmf = MemoryMappedFile.CreateNew( "mymappedfile" , 1000)) { using ( var stream = mmf.CreateViewStream()) { var writer = ne

.NET 4 BCL の新機能 (3) : SortedSet

.NET 4 BCL にはユニークな要素を保持するコレクション SortedSet が追加される。.NET 3.5 で追加された HashSet のようなものだが、SortedSet の方は名前からも想像がつく通り、各要素はソートされた状態でコレクション内に保持される。 赤黒木 ( 原文 では self-balancing red-black tree。なお、赤黒木についてはざっと検索した限り このページ が詳しく書いてある) で実装されているので、挿入、削除、検索の計算量は O(log n)。一方、HashSet は O(1)。ということで、通常は HashSet を使った方がいいようだ。ただし、 コレクション内の要素をソート状態にしておきたい 特定の範囲のサブセットを取り出したい 最小、最大の要素を取り出したい などの要求がある場合は SortedSet を使うとよいとのこと。   コードサンプル // これで set1 の中身は 1, 2, 4, 5, 6, 8 になります。 // 2 を2回追加していますが、2度目の追加は無視されます。 var set1 = new SortedSet< int >() { 2, 5, 6, 2, 1, 4, 8 };   // プロパティで最小、最大要素を取り出せます。 var min = set1.Min; var max = set1.Max;   // サブセットの取り出しも可能です。subset1 の中身は 2, 4, 5, 6 です。 var subset1 = set1.GetViewBetween(2, 6);   補足 GetViewBetween メソッドで得られるサブセットは面白い性質を持っている。オリジナルの「ビュー」なので、サブセットを変更するとオリジナルにも変更が反映されるのだ。また、境界外のデータを追加しようとすると例外が発生する (上のサンプルの場合は 2 から 6 の範囲でサブセットを取得しているので、例えば 9 を追加すると例外が発生する)。

.NET 4 BCL の新機能 (2) : ファイル IO の改善

.NET 4 では System.IO の読み込み系 API が改善され、遅延ロード用メソッドが追加されるらしい。 例えば File クラス。ReadAllLines というメソッドがあるが、メソッドを呼び出した時点でファイル内の全データをバッファリングするので、巨大なファイルを読み込むと return まで結構待たされることになる。この問題を解決するために、同様の処理を行う ReadLines メソッドが追加された。ReadLines は IEnumerable<string> を返すが、呼び出した時点ではデータを読み込まず、foreach などでデータを使おうとした際に初めてデータの読み込みを行う。 試しに 50 万行のテキストファイルを読み込んで、List<string> に各行を Add するプログラムを作って、ReadAllLines と ReadLines の処理時間を比較した。return が早い分、処理時間に多少コストがかかるかもと思いきや、全然そんなことはないようだ。   ReadAllLines ReadLines return までの時間 0.4 から 0.47 秒 0.02 から 0.1 秒 全行バッファリングまでの時間 0.67 から 0.74 秒 0.36 から 0.73 秒 DirectoryInfo クラスにも EnumerateFiles というメソッドが追加された。これも ReadLines と同じく IEnumerable<FileInfo> だけ return しておき、データを使う時に初めてファイルシステムからファイルの情報を取得する。 LINQ と一緒に使うと特に効果的だ。下のコードは MSDN マガジン に載っているもので、C:\logs フォルダにある拡張子 log のファイルから、Error: で始まる行だけを抜き出す処理。新 API を使うと、フォルダの全ファイルを取得する必要も、ファイルの全行を読み込んでくる必要もなく、条件にあったファイル、行だけが e

Gallio と MbUnit が v3.1 に

Gallio と MbUnit の v3.1 がリリースされた。新機能は ビデオキャプチャとテストレポートへの埋め込み RSpec .NET 4 のサポート Vsial Studio 2010 Beta 1 のサポート コントロールパネルアプリケーション 新しいプラグインモデルの採用と、それに伴う起動時のパフォーマンスの改善 内部デザインの変更 MbUnit の改善 MbUnit は RowTest ができるので前に少しだけ使っていたが、NUnit に比べて粗削りな感じがしたのと、NUnit にも RowTest 拡張があることを知ったので、最近はすっかりご無沙汰になっている。 ただ、ビデオキャプチャの機能が気になる。

CLR オブジェクトヘッダーの構造

Image
前の投稿 で Andrew Hunter 氏の “ Object Overhead: The Hidden .NET Memory Allocation Cost ” を和訳した。その時、オブジェクトヘッダーという単語が出てきたのだが、何なのかよくわからなかったので調べてみた。 本棚を漁ったところ、 Essential .NET に載っていた。実行時のメモリ内はこういう構造になっているとのこと (ただし、x86 の CLR 1.0 の動作を観察して得た結論らしい)。 オブジェクトヘッダーには同期ブロックのインデックスと型のハンドルの2つのフィールドがあって、多分インデックスが int、型ハンドルがポインタなので、オブジェクトヘッダーのサイズは 4 バイト + 4 バイト = 8 バイトなんでしょう。 ちなみに、同期ブロックのインデックスというのは ロックや COM オブジェクトなどの追加リソースをこのオブジェクトと関連付けるために利用 するものなんだそうです。 型のハンドルというのは、図で示されている通り、オブジェクトの実際の型を現す型構造体へのポインタです。

.NET 4 BCL の新機能 (1) - 新機能一覧

MSDN マガジン 2009 年 9 月号 に .NET 4 Beta 1 の BCL に新しく追加されたものについてのカラム ” What’s New in the Base Class Libraries in .NET Framework 4 ” が掲載されていた。 この投稿では新機能の一覧だけ掲載しておく。 コードコントラクトのサポート 並列処理の拡張 (タスク、並列コレクション、協調データ構造) タプルのサポート ファイル IO の改善 メモリマップドファイルのサポート SortedSet コレクション 任意の大きさの整数のサポート インターフェース、デリゲートでの Generic variance annotation 32 ビット、64 ビットレジストリビューへのアクセスと揮発性レジストリキーの作成のサポート グローバル化データ更新 リソース検索フェイルバックロジックの改善 圧縮の改善 Beta 2 ではさらにいくつかの機能を追加しようと思っているらしい。   これらについて勉強したら、個別の機能についてサマリーを投稿する予定。

目には見えない .NET のメモリアロケーションコスト

Simple Talk に興味深い記事が掲載されていた。 Andrew Hunter 氏が書いた “ Object Overhead: The Hidden .NET Memory Allocation Cost ”。以下はその和訳。 オブジェクトの保持には思いのほか多くのメモリが使われます (32 ビットか 64 ビットかによって違いますが)。32 ビットのシステムでは、各オブジェクトは 8 バイドのオブジェクトヘッダーを持ち、さらにどこかからの参照 (4 バイトのポインタ) が必要です。つまり、単純にオブジェクトが存在するだけで 12 バイト必要になります。 64 ビットだと状況はもっと悪くなります。16 バイトのオブジェクトヘッダーに 8 バイトのポインタ。オブジェクトが存在するためだけに 24 バイト必要です。小さなオブジェクトを大量に持っているようなアプリケーションの場合、32 ビットから 64 ビットへの切り替えはひどい状況をもたらすことでしょう。メモリ不足ということにはならないかもしれませんが、要求されるリソースは 3 倍に増えてしまいます (訳注:12 バイトから 24 バイトなんだから 2 倍では?)。 このオーバーヘッドによって .NET アプリケーションにオブジェクト数の制限が課されます。32 ビットシステムではオブジェクトが存在するためだけに 12 バイト必要であり、これは最大オブジェクト数は 1 億 7000 万くらいであることを意味します。しかし、これでは多くのオブジェクトは無価値です。これらのオブジェクトにはデータを持っていないのですから。4 バイトのデータを持たせると、最大オブジェクト数は 1 億 3000 万に減ります。この時、アプリケーションによって使用されているメモリの 75% はオーバーヘッド分であり、非常に非効率的です。 ここで、望ましい効率について考えてみます。.NET インフラによって消費されるメモリ量は、オブジェクトの数と平均サイズから算出することができます。例えば、オーバーヘッドを 10% にするためには、32 ビットシステム上のオブジェクトは平均 80 バイトのデータを保持しなければなりません(この時の合計サイズは 88 バイト。8 バイトのヘッダーは全体の 10% を占めるこ

5 分間で MVVM を概観する

Image
Data-Driven Services with Silverlight 2 という本を書いている John Papa 氏のブログ で「 5 Minute Overview of MVVM in Silverlight 」という役に立つ投稿があったので共有。 イントロダクションで、「多くの記事は MVVM が何か知っていることを前提に書かれているけれど、この投稿は MVVM 自体の簡単な説明です」と書かれている。今まさに注目されている技術というのは、知っている人たちでどんどん議論が進んでいって新参者は追いつくのが大変なので、こういう基本を勉強できるコンテンツはありがたい。 View View はユーザーインターフェースを表すクラスです。例えば Silverlight では MainPage.xaml や Page.xaml です。View はコントロール、アニメーション、ナビゲーション、テーマ、その他表示用の対話機能を持っています。Silverlight や WPF ではデータバインディングも View に含まれます。バインディングはデータのどのプロパティを使うかだけを指定していて、プロパティがどこからくるのか (つまりどのインスタンスにバインドされるのか) は意識していません。データソースが View の DataContext にセットされた時に、バインディングがアクティブになります。 View に関する別の意見 XAML 内のリソースで ViewModel を作って View にアサインすることがあります。私は View と ViewModel を分離して連携させる方が好きです。でも、リソースとして View の中で ViewModel を作るのはとてもポピュラーなようです。どちらの方法もいいところがあります。View の中で ViewModel を作ってしまうのは Blend を使う場合に簡単で効率がいいでしょう。View と ViewModel が疎結合であれば DI しやすさやテスタビリティを高めます。 Model 特定のエンティティとして表現されるデータを表すクラスです。例えば、CompanyName や CustomerId のようなプロパティを持った Customer クラスです。Cust

データは物理的にも論理的にも削除すべきではないのか?

InfoQ Japan に昨日 (9/13) づけで データの削除は非推奨 というニュースが公開された。内容をまとめると Oren Eini 氏曰く : 論理削除はデータが間違いを含んだ状態(例えば顧客エンティティが論理削除された注文エンティティを保持する)になりやすいよね。論理削除はやめた方がいいよ。 じゃあ、物理削除することにして、整合性を保つためにカスケード削除すればいいか。 Udi Dahan 氏曰く : いやいや、現実世界ではカスケード削除されないよ(カタログに載っている商品を「削除」しても商品自体への注文は一緒に消えてなくなることなんてない)。そもそも、現実世界で行われることは「削除」の一言では表しきれないじゃない。注文は削除じゃなくてキャンセルされるものだし、従業員は解雇とか退職、仕事は完了とか取り消しだよね。単純な IsDeleted フラグじゃなくて、有効、中止、キャンセル、廃止予定のような状態を持たせるべきじゃないかな。 つまり、物理削除も論理削除もしないほうがいいんじゃない?という話だ。   今の仕事について以来、関わったシステムはほとんど論理削除で設計されていたので、業務システムは論理削除が普通なんだと思って受け入れていたが、言われてみれば確かにそうかとも思う。データベースが、現実世界の情報をモデル化してシステム上で再現したものと考えれば、データの「削除」についても現実世界に即したものにすべきではないか。 僕の周りは論理削除が多いが、実際のところどうなのだろう? 現実に論理削除が多いのは、単純に Udi Dahan 氏のような視点がなかっただけなのか、それとも論理削除にメリットがあるのか?

Silverlight では XAML で Nullable 型プロパティに値を設定できない

Silverlight の XAML パーサーは、Nullable 型プロパティへの値設定に対応していないらしい(試したのは Silverlight 3)。XAML で Nullable 型プロパティに値を設定しようとすると、実行時に System.Windows.Markup.XamlParseException が発生し、 "AG_E_PARSER_BAD_PROPERTY_VALUE [Line: 8 Position: 60]" という意味不明のエラーメッセージだけが表示される。ちなみにパースの失敗なので、クラスに Nullable 型のプロパティが宣言してあっても、値を設定していなければ問題ない。 これに限らず、XAML 関係の例外(パースエラーとか)のメッセージをもっとわかりやすくしてもらえるとありがたい。WPF は当初に比べるとだいぶよくなってきたが、Silverlight はまだこのような意味不明メッセージが多いという印象を持っている。

LINQ を使って差集合を取得する

Image
Microsoft Visual Studio プログラムマネージャの Noah Coad 氏のブログ で 面白い投稿 を見つけた。 差集合取得操作をしたいと思うことが時々あるでしょう。つまり、集合 A の要素の中で集合 B に存在しないものだけを取得するという操作です。集合 A と B の型が同じであれば LINQ の Except メソッドでこれを実現できるのですが、集合の型が異なり、かつ ID をマッチさせなければならないということがよくあります。ここでは LINQ を使ってどうやってこれを実現するかという簡単な例をご紹介します。 Wolfram MathWorld によれば操作はこのように定義されます: private static void Main( string [] args) { List< string > names = new List< string > { "Noah" , "Sarah" , "Josiah" , "Craig" , "Carolin" }; Dictionary< string , string > visiting = new Dictionary< string , string >() { { "Noah" , "Turkey" }, { "Craig" , "Germany" }, { "Sue" , "Bangalore" } }; var minus = from n in names let places = from p in visiting select p.Key where !places.Contains(n) select n; foreach ( var v in minus) { Console.WriteLine(v); } Conso

WPF のレイアウトシステムに連動する Web ブラウザコントロール

Image
Chris Cavanagh という方が Google の Chromium とか、 Awesomium をベースに、WPF の Web ブラウザを作っている。 Chris 氏によれば WPF で Web ページをレンダリングし、Web ページと連携できるようにすることは大きく可能性を広げます。WPF には WebBrowser コントロールが組み込まれていますが、これは IE の ActiveX コントロールのラッパーであり、残念ながら WPF レイアウトシステムに連動しません。 というのがモチベーションになっているらしい。確かに、WebBrowser コントロールは TextBox や Button などの一般的なコントロールに比べてちょっと特殊(例えば Opacity が効かない)な挙動をするので、レイアウトシステムときちんと連動してくれる WebBrowser ライクなコントロールがあるとありがたい。 ちなみに、すでにデモアプリを試すことができる。下のスクリーンショットは このページ からダウンロードしたもの。見ての通り、ブラウザ画面に WPF のエフェクトをかけることができている。 これは YouCube という名前の WPF 3D Web ブラウザ。 このページ からデモアプリをダウンロードできる。

外部フォルダのアセンブリを動的にロードする

アプリケーションがおいてあるフォルダの外にあるアセンブリを、カレント AppDomain に動的にロードする方法。 Dynamic Loading of .Net Assemblies ロードしようとしているアセンブリが見つからない場合に AppDomain.AssemblyResolve イベントが発生するので、このイベントのハンドラで追加のアセンブリロード処理を実装すればよい。 public class Bootstrap { private static void Main( string [] args) { AppDomain.CurrentDomain.AssemblyResolve += SearchAssemblyFromDirectories; string [] directories = new string [] { @"C:\asm" }; AppDomain.CurrentDomain.SetData( "directories" , directories); Assembly asm = Assembly.Load( "MyAssembly" ); foreach (Type type in asm.GetTypes()) { Console.WriteLine(type.FullName); } Console.ReadKey(); } private static Assembly SearchAssemblyFromDirectories( object sender, ResolveEventArgs e) { string [] directories = ( string [])AppDomain.CurrentDomain.GetData( "directories" ); foreach ( string dir in directories) {

WPF/Silverlight の Canvas 内のコントロールを動的にレイアウト変更する

Image
こんなことをやろうとしている。 (1) Window や Page から CanvasLayoutManager に対して状態遷移を指示する。この時、次の状態の名前を指定する。 (2) CanvasLayoutManager が指定された状態のレイアウトを取得し、現在のレイアウトと遷移後のレイアウトの情報をマージする。 (3) アニメーションを使って Canvas 内のレイアウトを変更する。 つまり各コントロールのレイアウト情報を外だしで定義しておいて、それを状態という形でグループ化して複数定義できるようにし、状態を切り替えることで動的なレイアウト変更を可能にしようとしています。 状態を各状態を保持した CanvasLayoutDefinition は XAML 内にリソースとして記述することを想定している。レイアウトには各コントロールのサイズ、位置、透明度を指定できるようにしていて、サイズと位置は Canvas のサイズと Canvas 内の相対位置をもとに割合で指定できるようにと考えている(例えば、Top=0.5、Left=0.5、Height=0.3、Width=0.3 と指定したら、コントロールの左上が Canvas の真ん中に来てサイズは Canvas の 0.3 倍になる)。 WPF 版の実装は大体できていて、これから Silverlight にポーティングしようとしている。完成したら CodeProject で公開予定。

Doloto : Web 2.0 アプリケーション最適化ツール

Image
MSDN DevLabs のフィードを流し読みしていたら “ Doloto ” が目を引いたので、少し調べてみた。 Doloto は AJAX を使ったアプリケーションを最適化するツール。アプリケーションから JavaScript を分離してスタブに置き換え、最初にページを表示する時にロードする JavaScript コードの量を減らすことで、初期表示時間を短縮する。実際の JavaScript コードは、最初に実行しようとしたタイミングでダウンロードされる。 それから、 Somasegar 氏のブログ に Doloto の実行手順が書かれている。 Doloto はスタンドアローンのクライアントサイドツールで、次の3つのステップで動作します。 アプリケーションをプロファイリングします。Doloto はローカルプロキシを実行してプロファイリングを行い、JavaScript をインターセプトして、ブラウザに依存しない方法で各 JavaScript 関数の実行時のタイムスタンプを取得できるようにします。 プロファイリング情報はコードカバレッジとクラスタリング戦略を見積もるために使われます。これは関数をスタブ化するのか、もしくはまとめてダウンロードされるようにグルーピングするのか(クラスタと呼ばれます)を決定します。 JavaScript コードを書き換えます。ローカルディスクに保存されるので、それをサーバーにアップロードしてください。全ての処理はサーバーにアクセスせずに、ローカルマシン内で実行されます。そのため、サードパーティのサイトを、それらのサーバーにアクセスせずにプロファイリングし、最適化できます。Doloto の処理結果に満足できた時点で、サーバーにファイルをデプロイすることができます。 また、同じく Somasegar 氏のブログ に Doloto の最適化の結果が掲載されている。 我々が行った多くの AJAX アプリケーションへのアクセス実験の結果、Doloto は JavaScript コードの初期ダウンロード量を 40% 以上減らし、アプリケーションの立ち上がりを 30 ~ 40% 高速化しました(ネットワークの条件に依存しますが)。このグラフは、ポピュラーな Web サイ

ソースコードに色付けするためのライブラリ ColorCode 1.0 リリース

CodePlex でソースコードをスタイル設定済みの HTML に変換するライブラリ ColorCode のバージョン 1.0 が公開された。ちょうど C# でこういうことをやりたいと思っていて、気になったので共有。 サポートされている言語は XML JavaScript SQL C# VB.NET ASPX (C# & VB.NET) C++ PHP 使い方は非常にシンプル。 using ColorCode; using System; using System.IO; namespace ConsoleApplication1 { class Program { static void Main( string [] args) { string source = File.ReadAllText( @"C:\tmp\Program.cs" ); CodeColorizer colorizer = new CodeColorizer(); string result = colorizer.Colorize(source, Languages.CSharp); File.WriteAllText( @"C:\tmp\Program.htm" , result); } } } ちなみに、ここに貼ったコードはこのサンプルプログラムの実行結果(フォントファミリーだけ等幅に変えたが)。C# しか試していないが、型の色以外は Visual Studio のデフォルトカラーとほぼ同じになった。

30 秒で単体テストの問題点を探し出す8つのテクニック

Roy Osherove 氏の投稿 “ 8 techniques to find problems in your unit tests within 30 seconds ” より。 信頼性の点から テストプロジェクトで “DateTime.” を使っているところを探してください。 DateTime を使っているということは、本質的に毎回異なる単体テストを走らせていることになります。もし DateTime が原因でテストが失敗し、その時使われた値のログをとっていなければ、失敗を再現するのは困難でしょう。 テストプロジェクトでスレッドを使っているところを探してください。 スレッドを使っていると、ロジックではなくスレッドのせいでテストが失敗してしまうでしょう。低スペックマシンやマルチ CPU のマシンで動かした時さえ、テストの動きが変わります。結合テストならよいのですが、常に同一の結果になる必要のある単体テストにとっては問題です。 “Environment.” を探してください(newline は除いて)。 現在の環境に依存したものを使っている場合、2つのことが起こりえます。テストマシンが変わると異なるテストをすることになり、テストはプロダクションコードの中のロジックを繰り返します。代わりに、環境変数のフェイクを使い、期待値をテストコード内にハードコーディングすべきです。そうでなければ、結合テストをすべきです。   メンテナンス性の点から Resharperを使って “.Verifiable” メソッドを探し、メンバーでグルーピングしてください。 この時、テスト毎に1つであるべきです。そうでなければ、1つ以上のことについてテストしていることになります。そして、内部動作を過度に指定しているのでより脆弱なテストになってしまっています。コードの変更があったら、テストはすぐに動かなくなってしまいます。 Moqを使っているなら、".VerifyAll”を探してください。 これも内部動作の過度な指定で、テストを脆弱で失敗しやすいものにしてしまいます。検証は1つのモックオブジェクトだけにすべきです。 Rhino Mocks を使っているなら、AssertWa

ADO.NET Data Services CTP1 と CTP2 の比較

Marcelo 氏のブログ で ADO.NET Data Services CTP1、2 の機能比較表が公開されている。 Marcelo 氏の投稿 によれば、CTP2 で新しくなったのは以下の点とのことだ( ADO.NET Data Services Team Blog の情報をもとに一部補足)。 機能 CTP1 で使える? CTP2 で新しくなったこと プロジェクション   追加された。 データバインディング ○ 型が整理された。 (例えば DataServiceCollection) 行数カウント ○ バグフィックス。API 自体は CTP1 と同じ。 フィードカスタマイズ ○ 属性の名前が変更された。 より柔軟になった。 サーバードリブン ページング ○ .NET と Silverlight 3 用のクライアントライブラリが追加された。 BLOB サポート拡張 ○ .NET と Silverlight 3 用のクライアントライブラリが追加された(サーバー側は CTP1 からサポートされていた)。 リクエストパイプライン   追加された。 プロバイダ インターフェース ○ API がリファクタリングされた。

ADO.NET Data Services v1.5 CTP2

ADO.NET Data Services v1.5 の CTP2 が公開された。 ADO.NET Data Services v1.5 CTP2 – Now Available for Download マイクロソフトダウンロードセンターから ダウンロードできる 。CTP2 は CTP1 の機能のアップデートの他、新機能と数多くのバグフィックスが含まれている。以下は、CTP2 に含まれる機能についての説明をおおまかに訳したもの。 プロジェクション : プロジェクションを表現するために URI フォーマットが拡張されました。CTP2 にはサーバー、クライアント両方のライブラリでプロジェクションがサポートされます(LINQ のサポートも含みます)。この機能については今後の投稿で詳細を説明しようと思っています。 データバインディング : データサービスクライアントライブラリが拡張され、WPF や Silverlight ベースのアプリケーションで Two-Way バインディングが可能になりました。 行数カウント : ADO.NET Data Services V1 リリース後、クライアントに全エンティティを持ってくることなしにエンティティ数を取得したいというフィードバックが数多く寄せられました。このニーズに応えるために、全エンティティをダウンロードせずにこの種の情報を取得できるよう、データサービスアドレス方式を拡張しました。 フィードのカスタマイズ(いわゆる Web フレンドリーフィード) : エンティティが AtomPub の各種要素にどうマッピングするかをカスタマイズする機能の提供について多くの質問を受けていました。この機能は、エンティティのプロパティとフィードの要素をデータサービスランタイムがどうやってマッピングするかを、データサービスの作成者が宣言的にコントロールできるようにするものです。 サーバードリブンページング (SDP) : この機能は、各リクエストに対して返すエンティティの総数を制限するものです。さらに、サーバーはクライアントに「next link」、つまり次のエンティティを取得するためのシンプルなURIも提供します。 BLOBサポートの拡張 : ADO.NET Data S

WPF の RichTextBox でキャレットがあるパラグラフを強調表示する

Image
入力補助の一環として、現在編集中の(つまりキャレットがある)パラグラフがわかりやすいように強調表示する方法を考えた。 まずは XAML 定義。ここで大事なのは RichTextBox の SelectionChanged イベントだ。名前からすると、テキストを選択状態にした時に発生しそうなイベントなのだが、実はキャレット移動時に発生する。この SelectionChanged イベントのハンドラで強調表示の切り替えを実装する。なお、Style と Resource の定義は、それぞれデフォルトの文字スタイルと、強調表示用の文字スタイルの定義である。 <RichTextBox Name="richTextBox" SelectionChanged="Highlight"> <RichTextBox.Style> <Style TargetType="RichTextBox"> <Setter Property="FontFamily" Value="MS UI Gothic"/> <Setter Property="FontSize" Value="12"/> </Style> </RichTextBox.Style> <RichTextBox.Resources> <Style x:Key="selectedBlock" TargetType="Block"> <Setter Property="Background" Value="LightBlue"/> <Setter Property="FontSize" Value="16"/> </Style> </Ric

WPF のステータスバーに表示したテキストをフェードアウトさせる

ステータスバーにメッセージを表示し、一定時間経ったら消す、という処理を実装する際、今回はただ消すだけではなくてフェードアウトしていくような消し方を考えてみた。 まずはステータスバーの配置とアニメーションの定義。メッセージを5秒間普通に表示した後、1秒間でフェードアウトして消えるようにしている。 <StatusBar> <StatusBarItem> <TextBlock Name="textBlock"> <TextBlock.Resources> <Storyboard x:Key="fadeStoryboard"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="textBlock" Storyboard.TargetProperty="Opacity"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/> <SplineDoubleKeyFrame KeyTime="00:00:05" Value="1"/> <SplineDoubleKeyFrame KeyTime="00:00:06" Value="0"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </TextBlock.Resources> </TextBlock> </StatusBarItem&

WPF の RichTextBox に文字列を設定する&取り出す

WPF の RichTextBox は内部に FlowDocument オブジェクトを持っていて、一部分の文字のスタイルを変えたり、表や画像を表示したりといった高度な文章表現ができるが、普通の TextBox と違って Text プロパティを持っていないので、直接文字列を読み書きすることができない。少々面倒だが、FlowDocument からテキスト領域を取り出して、そこに対して文字列を読み書きする、という風に実装しなければならない。 文字列の取得、設定でキーになるのが TextRange クラス。XAML で <RichTextBox Name="richTextBox"/> のように RichTextBox を宣言していたとすると、文字列の設定は FlowDocument document = this.richTextBox.Document; TextRange range = new TextRange(document.ContentStart, document.ContentEnd); range.Text = "ABCDEFG"; となる。設定する文字列がテキストファイルから読み込んだ文字列で、途中に改行が入っている場合は、1行1パラグラフになる。逆に文字列の取得は FlowDocument document = this.richTextBox.Document; TextRange range = new TextRange(document.ContentStart, document.ContentEnd); string text = range.Text;

WebBrowser コントロールの文字化け解消

.NET 3.5 SP1 で WPF に追加された、WPF の画面に Web ブラウザを埋め込んで Web ページを表示させることのできる WebBrowser コントロール。URL や ファイルのパスを指定して Web ページを表示させることができる以外にも、NavigateToString(“<p>Contents</p>”) のように NavigateToString メソッドを使って String として保持している HTML を直接レンダリングさせることもできる。だが、WebBrowser コントロールを使ってみたところ、日本語が文字化けしてしまった。 プロパティやメソッドでエンコーディングを指定する方法はないようだが、 このページ に回避方法が書かれていた。要は .NET からではなく、META タグで HTML 自体にエンコーディングを指定すればよいらしい。 <html> <head> <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'> </head> <body> … </body> </html>

TechEd2009 参加(3日目)

参加セッション ◆ T6-302 マイクロソフトにおけるアジリティを向上させる開発プロセスへの試み マイクロソフト社内の開発プロセスとか TFS をどう使ってるかとかいった話。 Visual Studio開発部門の開発プロセスと TFS の使い方が結構具体的に解説されていて面白かった。開発のライフサイクルが「ビジョン・主要なテーマ」-「投資効果、顧客価値の大きい領域」-「機能」-「具体的な作業」という階層で表現されていて、それが TFS の作業項目にマッピングされている。これを上から下へも、下から上へもトレースしていけるようになっていて、簡単にプロジェクトの状況が把握できるらしい。 僕が入社した頃から最近まで業務で TFS を使っていて、テンプレートのカスタマイズ(ウォーターフォール化)もやっていたんだけど、Microsoft の TFS の使い方を見ると全然活用できてなかったなぁと感じた。業務でもう触る機会はないだろうから、どうにか業務外で TFS を使う機会を作って Microsoft のテンプレートを一度試してみたい。   ◆ T2-405 ADO.NET Entity Framework アーキテクチャ & ストラテジ ADO.NET Entity Frameworkを使ってどのように生産性向上やデータアクセス層の汎用化を実現するかという話。   ◆ T2-308 Windows 7 のためのアプリケーション開発 既存のアプリケーションをどう Windows 7 に対応させるか、Windows 7 独自の機能をどう取り込んでいくかといった話。 Windows 7 で強化されたところ(Explorer、JumpList、Thumbnail など)と、新機能(マルチタッチ、センサー API など)を活用してどういうことができるかという内容が中心だった。SDKのトレーニングキット?スターターキット?に実装サンプルがあるらしい。   ◆ T2-201 Visual Studio 2010 & .NET Framework 4 概要 Visual Studio 2010 と .NET 4 で追加される予定の機能の概要の話。

TechEd2009 参加(2日目)

参加セッション ◆ T2-312 あなたの身近な Office 開発の世界 VSTO を使った Excel と ADO.NET Data Services の連携や、OpenXML の API を使ったサーバーサイドでの Excel ファイル生成の話。 OpenXML の API を使うと、COM 経由に比べて相当高速にファイル生成ができていた。デモで COM は使っていなかったけど、これまでの経験からすると全然早さが違った。   ◆ T2-401 Deep Dive into .NET Framework CLR アセンブリの中身がどうなっているかという話。 CLR の動作についての Deep Dive かと思いきや、アセンブリの PE ヘッダがどうなってるとか、メタデータがどう格納されてるとか、アセンブリの構造に終始した。   ◆ T2-309 ADO.NET Entity Framework and LINQ データ アクセス開発 ADO.NET Entity Framework でのデータモデリング、パフォーマンスチューニング、エラーハンドリングの話。   ◆ T2-311 64 ビット アプリケーション開発のポイント 64bit アプリ開発、というより 32bit から 64bit への移行で気をつけなければいけないポイントの話。 コーディング上で気をつけなければならないのは、ポインタのサイズと構造体のアラインメント。開発は .NET 上でしかやってないし、アラインメントいじるほどの最適化をしていないので、この辺は気にしなくてよさそう。 ただ、64bit 上で 32bit アプリケーションを動かす WOW64 (Windows on Windows 64) 上でアプリケーションを実行される可能性がある時は .NET でも色々気をつけないといけないみたい。WOW64 とそうでない場合とで環境変数が違う場合があったり、.NET が 32bit、64bit 両方インストールされるので machine.config が 32bit 用、64bit 用2つできてしまったりする。 あと、JET OleDb ドライバは 32bit 版しかないらしい。僕は ADO.NET で Excel にアクセスするためによく使ってるので、頭の片隅に入れ

TechEd2009 参加(1日目)

TechEd2009 に行ってきた。   参加セッション ◆ T1-311 Windows 7 と Windows Server 2008 R2 の新機能を活かして実現! より安全な IT インフラ アプリケーションの実行を制限する AppLocker と、リムーバブルディスクを暗号化する BitLocker to Go の話。 AppLockerはソフトウェア制限ポリシー (SRP) の強化版で、グループポリシーエディタでホワイトリストベース、ブラックリストベースのアプリケーション利用制限がかけられるものらしい。特定のフォルダ内のみ許可とか、特定のバージョン以上許可とか、結構柔軟に制御できるように見えた。ただ、自分はこういうものを導入する立場ではなくて、むしろ制限をかけられる側なので、正直うざいなぁと思って聞いていた。 もう1つの BitLocker to Go はリムーバブルメディアを暗号化する機能で、Vista で導入された BitLocker の拡張みたい。基本 WIndows 7/Server 2008 R2 で動くけど、暗号化した時に FAT でフォーマットされた隠しパーティションができて、そこに暗号領域読み取りツールが配置されるから、XP でもその読み取りツールで中が見えるとのこと。便利そうなんだけど、個人的にも業務でも USB メモリを持ち歩くことがないので、今のところ使い道がない…   ◆ T1-401 Windows 7 と Windows Server 2008 R2 カーネル解説と基本機能の強化 Windows 7、Windows Server 2008 R2 のカーネルがモジュール化、パフォーマンス、パワーマネジメントなどの面でどう変わったかの話。今日聞いた中で一番面白かったセッション。カーネルは専門じゃないので難しかったけど。 コンポーネント化 :OS として最低限必要なものを MinWin としてまとめ、既存の DLL (kernel32.dll とか advapi32.dll とか) をリファクタリングして別 DLL にまとめたらしい。ただ、Virtual DLL という機能で DLL 解決することで既存のアプリも問題なく動くみたい。後、cmd.exe のメッセージングループを CSRSS から

お引越し

某所のブログを止めて引越ししてきました。