.NETの例外処理 Part.1

さて次は何を書こうかなぁと思ってましたが、前回のエントリのウケが比較的よかった様子なので、もうちょっと初心者向けのエントリを続けてみようと思ったり。ということで、今回は .NET の例外処理について書いてみたいと思います。 なぜにいまさら例外処理……? と思われる方も多いと思うのですが、理由はただ一点。現場レベルのソースコード読んでると、未だに例外処理がめちゃくちゃなアプリがホントに多いのです。 私が昔、Java を初めて触ったときに感動した機構の一つが例外処理(とそれに関連するスタックトレース)で、例外処理を正しく書くだけで、アプリの内部動作の大部分はわかるし、障害解析も圧倒的にラクになる。しかしその一方で、例外処理についてわかりやすくまとめられた書籍が少ないために、なかなか理解するのが大変なところでもあるんですよね。自分の書いた開発技術大全 vol.3 だけではどうもまだ分かりにくいようなので、少し加筆しながらここで説明しよう、と思った次第です。そんなわけで、今日は比較的初心者向けのトピックですが、気楽にお付き合いいただけると嬉しいかもです。 # といいつつ、たぶんそんなに気楽に読めるエントリでもないかもしれません。 # 例外処理は、実はアプリケーションデザインにもかかわる部分があり、例えば BC や DAC の # メソッドの引数・戻り値の設計にも影響を与えてくるからです。なので、一度じっくり腰を据えて学習 # してみてください。一度きちんと勉強すれば済む話ですので^^。 まず、そもそも .NET アプリケーションにおける「例外」は、どのような状況を表現するために用意されている機能なのか、というところから解説していくことにします。 [.NET アプリケーションにおける例外と業務エラーの違い] 一般的に、業務アプリケーションを開発する場合には、業務フローチャートを作成し、その流れを C# や VB のコードによって実装します。 通常、業務処理の終了(=各メソッドの終了)は、正常終了と業務エラーのパターンに大別されますが、例外はこうした正常終了や業務エラーを表現するために利用してはいけません。例外はその名の通り、例外的な状況、すなわち業務フローチャートからはみ出してしまったという、想定外の事象を表現するために利用します。 具体的には、データベース接続エラーやネットワークエラー、メモリ不足などが発生した場合には、この状況を例外によって表現する、というのが .NET における大原則、と理解してください。 しかし、この例だけだと分かりにくいと思いますので、もうちょっと具体的な例を取り上げて説明してみましょう。例えば、重複ユーザ ID の利用を認めないような、新規顧客登録業務を考えてみます。 このような業務アプリにおいて、どのようなケースが業務エラーに相当し、どのようなケースが例外に相当するのかを考えてみます。ボタンを押したあとの応答は、以下の 3 つのパターンに分類できますが、.NET アプリケーションでは、③のパターンのみを例外とし、②のケースを例外として表現してはならない、というのがポイントになります。 この説明だけだとまだ業務エラーと例外の違いがわかりにくいので、もう少し突っ込んで説明をしてみます。 今、このアプリケーションで③に相当するケース、すなわちデータベース接続エラーやネットワークエラーが発生したとします。通常、これらのエラーはエンドユーザに対して通知するべき内容ではありません。というか、「データベースに接続できませんでした」、とかいわれても、エンドユーザ側としてはどないせいっちゅーねん、状態になりますよね?^^ おそらくこのような場合には、エンドユーザに対しては「ごめんなさい、またしばらくしたらアクセスしてください」「ヘルプデスクに電話してください」などのメッセージを通知するようにし、エラーの詳細情報は隠ぺいすることになるでしょう。 ところが、ID 重複エラーのようなものは、エンドユーザ側で対処のしようのある状況です。このような場合には、エンドユーザに対して適切なガイダンスメッセージを表示し、再入力などを求めることになるでしょう。 このように考えてみると分かりやすいと思いますが、 .NET における「例外」とは、エンドユーザに対して通知すべきではない、「システム的・アプリ的な異常事態」が発生した場合に利用するもの。(上図の下側のような画面を出さなければならないケースは例外、ということです。) それ以外の場合、すなわちエンドユーザに対して再試行を促すようなメッセージを表示することになるケースを業務エラーと呼ぶ。業務エラーでは、例外を利用してはいけない。 というのが .NET 開発における原則、ということになります。 [2…

9

続・スレッドとオブジェクトインスタンス

さて、実は次のエントリは別の内容を書こうと思っていたのですが(現在書きかけ中)、質問がコメントで出ていたので、こちらを明確にしてから次の内容に進むことにします。(わからないことをそのままにしないのはめっちゃ重要ですからね~^^) kazenami さんと HashedBeef さんのお二人のご質問に共通するポイントは、おそらく スレッドはどのようにして開始されるのか? オブジェクトインスタンスは、どのようにして生成され、どのようにして各スレッドのスタックメモリ内の変数に割り当てられるのか? というところだと思います。前回のエントリでは、この部分をあやふやにして書いたために、きちんと考えようとすると、とたんに行き詰まりますよね^^。というわけで、もうちょっと補足しようと思います。 [3 種類のスレッド] .NET アプリケーションの内部では、基本的に 3 種類のスレッドが動作しています。 メインスレッド そのプロセスに最初に作られ、Main() メソッドを動作するために使われるスレッド。 マニュアルスレッド バックグラウンドタスクを行うために、自力で作り起こすスレッド。System.Threading.Thread クラスのインスタンスを作ることで作成できる。 プールスレッド バックグラウンドタスクを行う際、CLR の機能であるスレッドプール機能を用いる際に利用されるスレッド。 これ以外にも、ファイナライザスレッドやアンマネージスレッドなどが動作しているのですが、とりあえずは上記 3 つを覚えれば十分。メインスレッドについては前回の説明でカバーされているので、ここではマニュアルスレッドとプールスレッドについて解説します。 [マニュアルスレッドについて] まず、マニュアルスレッドから解説しましょう。マニュアルスレッドとは、Thread クラスのインスタンスを作ることで新規にスレッドを起こすというもので、下のコードのようにして作成することができます。細かいコードは覚える必要はありませんが、コード上、以下の点に注目してください。 マニュアルスレッドを新規作成する場合には、そのスレッドで何の処理をするのかを指定する必要がある。下記のコードの場合、Task() というメソッドを新規 Thread インスタンスの引数として渡すことにより、この Task() メソッドをマニュアルスレッド上で開始することができる。 スレッドには、フォアグラウンドスレッドとバックグラウンドスレッドの二種類があり、スレッドの IsBackground プロパティにより変更することができる。アプリケーションプロセス内のすべてのフォアグラウンドスレッドが終了すると、プロセスが終了する形となる。(=下のコードにおいて、IsBackground プロパティを false にして実行すると、Main() 関数が終了しても、プロセスは生き残り続けます。) 1: namespace ConsoleApplication1 2: { 3: class Program 4: { 5: static void…

8

スレッドとオブジェクトインスタンス

さてさて、この blog、基本的には玄人向けに濃い話題ばっかり書いていたのですが、実は最近、新人さんの方々にも割と読んでいただいていることが判明。ちょ、さすがにぜんぜん意味不明なエントリが多いのでは?? とか思ったりするのですが、そんな感じだとたまには割と入門者向けのエントリも書いてみたくなります。そんなわけで、今日はたまには基本に立ち返って、スレッドとオブジェクトインスタンスの話題を書いてみます。このネタを取り上げようと思ったのは、ある人からの質問メール。(ちょっと微修正しましたが^^) 「最近、3 階層のアプリケーションを、課題で作っていたんですよ。 そして、その UI 層の入力チェックメソッドを、 メンバメソッドにすべきか static メソッドにするかを考えていて、 ふと気になったことがあります。 static メソッドだと、メンバメソッドと違って、毎回インスタンスを 生成する必要がなく、便利ですが、物理的に一つしかないので、 二つのスレッドから微小時間ずれてアクセスされると、トラブルが 起こるんではないでしょうか?」 これは非常によい視点、だと思います。というのもアプリケーション開発者にとって重要なのは、どうすれば動くかではなく、どうするのが正しいのか、だからです。単純に動くかどうか、だけでいえばメンバメソッドだろうと static メソッドだろうとどっちで書いても動くように見えるはずですが、過負荷状態になったときにもしかしたらトラブルになるかも? だったらどう書くのが正しいのか? ……というように論理的に考えることは非常に重要です。というわけで、この質問に敬意を表して、全力で答えてみたいと思います^^。 この質問、もうちょっと具体的な例として書いてみると、例えば UI 層のチェックメソッドを以下のように static メソッドとして実装した場合に public class DataCheckUtil { public static bool CheckEmailString(string email) { if (Regex.IsMatch(email, @"\w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*") == true) { return true; } else { return false; } } } これが Web…

15

Windows CardSpace 概要 Part.2

さて、前回は Windows CardSpace の理解をするために必要な前提知識として、そもそも現実世界におけるカード認証の仕組みについて解説しました。キーポイントとなる考え方はこれです。 自分のお財布の中には、公的機関や企業などから発行された、各種の名刺が入っている。(場合によっては自分がねつ造した自前の名刺が入っていることも!) お酒を買おうとするときは、酒屋さんから指定されたカードを、お財布の中からチョイスして提示する。 Windows CardSpace は、この現実世界におけるカード認証の動きを、コンピュータシステムの世界の中で実現しようとするものです。 [Windows CardSpace をサポートする Web サイトの動き] では、まず Windows CardSpace による認証をサポートする Web サイトが、どのようなものになるのかのイメージを見てみます。 通常の Web サイトでは、ユーザ名/パスワードによるログイン認証画面が用意されています。 Windows CardSpace をサポートしているサイトでは、さらにこれに加えて、CardSpace ログインボタンが用意されています。 このボタンをクリックすると、ブラウザから ActiveX コントロール経由で、クライアント PC 内にあるカードセレクタがポップアップとして起動します。(※ .NET Framework 3.0 がインストールされていない PC ではエラーになります。) このカードセレクタは、簡単にいえば「当該 PC の中にあるお財布」です。 この中に入っているカード(これを情報カード(Information Card)と呼びます)のうち、当該 Web サイトに対して提示可能なカードが表示されます。提示不可能なカードについてはグレーアウトされます。(先の酒屋さんの例で言うと、パスポートや健康保険証のみが提示可能なカードとして取り扱われ、その他の社員証カードなどについてはグレーアウトすることになります。) カードをダブルクリックすると、Web サイトへのログインが完了します。 ……と、このように、まさに「現実世界におけるカードの提示」と同じような方法で Web サイトにログインできることになります。 ちなみに現実世界の場合、お財布の中にカードがあふれかえっている人は少なくないと思いますが(自分もそうですが;)、コントロールパネルの "Windows CardSpace" という項目から、この PC…

9

コミュニティ関係で最近見かけたいい記事

を 2 つほど紹介してみたり。 ■ Microsoft の中の人ブログ集 わんくま同盟のシャノンさん(aetos さん)による、Microsoft の人たちの blog 集。実はお恥ずかしながら私は MSDN/TechNet のブログ一覧ぐらいしか知らなかったのですが、まさかこんなにあるとはびっくりです。必ずしも開発系/ITPro 系だけではないのですが、いやはやホント多いですね。 ■ .NET の新データアクセス・テクノロジ「ADO.NET Entity Framework」 これは正確にはコミュニティの記事ではなく、@IT に掲載されている記事ですが、コミュニティでも活躍されているナオキさんと山田祥寛さんのお二人による、ADO.NET Entity Framework の解説記事。これは非常によい記事で、ADO.NET Entity Framework の基本がざっくり 10 分程度で理解できると思いますのでぜひご一読を。実は ADO.NET Entity Framework については紹介記事を自分も書きたいなぁと思ってたのですが、基本的な内容はこれで網羅されているのでもう充分……かも(笑)。 # しかしなかなか時間がない….ちなみに今日も会社です(涙)。

1

Windows CardSpace 概要 Part.1

さて、次は何のネタ書くかなぁ……と思っていたのですが、ちょっと寄り道して Windows CardSpace (WCS)の話題にしてみようかと思ったり。 Windows CardSpace というのは、.NET Framework 3.0 に含まれるコンポーネントの一つで、 WPF (Windows Presentation Foundation) WCF (Windows Communication Foundation) WF (Windows Workflow Foundation) WCS (Windows CardSpace) と、.NET Framework 3.0 の一角を占める重要なコンポーネント…なのですが、これがびっくりするほど知られていません。確かに私も実際の案件で使ったことがあるテクノロジではなく、また現時点で利用しようと思うとハードルの高い技術なのですが、考え方は非常に単純であり、概要については知っておいて損はない技術の一つです。特にセキュリティがらみの技術は、実際にそれを使うにせよ使わないにせよ、設計概念を理解しておくと、実際のシステム開発ではその類推で設計できることが結構あります。幸い、概念レベルで見ると非常に面白い技術なので、今回は気楽にエントリを読んでもらえると嬉しいです。 Windows CardSpace とはどんなものか? 現実世界のカード身分証明との比較 コンピュータシステムとの比較 1. Windows CardSpace とはどんなものか? Windows CardSpace は、.NET Framework 3.0 に同梱されているコンポーネントです。このため、Windows Vista には最初からインストールされており、XP などでも .NET 3.0 をインストールすることで利用することができるようになります。ちなみに、どこにインストールされているのかというと、コントロールパネルの項目の中に「Windows CardSpace」という項目があり、これを選択すると起動します。   とはいえ、この画面だけだと「いったいこれはなに??」となると思います。この画面は、この PC の中にある「お財布」と、そこに含まれる「カード」なのですが、この説明でもさっぱりわからないと思いますので、ちょっと…

3

あしあと気軽に残してくださいー^^。

というわけでここまで毎週欠かさずエントリをアップしてきたのですが、今週は一週間お休み。(すみません、単に本業が忙しくてエントリを書いている時間がないからです。ネタはいろいろあるのですが;) ところで先日の話ですが、ある飲み会での話。 ここの blog ってぜんぜんコメントやトラバがついていないのですが、あまりにもコメントやトラバが少なすぎて読んでもらえているのかどうかわからない(フィードバックがないと全くわからない)という話をしたら、そもそも書き込みしにくい、というツッコミが;。 聞いてみると、要するにコメントつけたりトラバつけたりすると、コミュニティの人たちから売名行為と思われるかもしれないので怖くてつけられない、という話……だったのですが。 いやー、もしかしたらそうなのかもしれませんが。 書き手からすると、コメントついていないとめっちゃさびしいんですよ(苦笑)。 書籍を書いてるときはまさに文字通り「孤独との戦い」なわけですが、割と双方向コミュニケーションが取りやすい blog という形式ですらコメントやトラバがこうもつきにくいとは思ってなかったんですよね。 もともとツッコミ入れにくいエントリなのかなぁとも思うのですが、やはり Web 上では「知の集積」というのが大切なのではないか、と自分は思っています。これは英語圏の blog を読んでいて思うのですが、文化的にフランクに声を掛け合う側面が強いせいか、お互いに気軽に blog にコメントをつけあったりしている。特に自分の blog に追加情報を書いたりだとか、こんなこともあるよ、こんな場合はどうなの? みたいな話が結構充実しているので、結果的に知識がどんどん Web 上に集積されていき、それがみんなの生産性を高めていく、という傾向があるんですよね。そういう意味でも、気軽にコメントもらえたらなー、と思っていたりします。 # ……単にさびしいだけだろ、とかいうツッコミはなしでw。 # でもたぶん、コメントがついてないのはうちだけではなくて他の blog も結構同様? 書き手はフィードバックに餓えているものなので、「役に立ったよー」「つまらなかった」「もっとギャグを増やせ」とかなんでもいいので(笑)、ぜひフィードバックをお願いします^^。 しかし次回は何にしようか考え中。流行りでは Azure なのでしょうけど、現実の今日の業務とはちょっと離れるので、うちの blog で扱うべきかどうかは迷いますねぇ……。

13

Part 3. ASP.NET 2.0 Web アプリケーションの 64 ビット対応

さて、前回のエントリではコンソールアプリケーションやライブラリアプリケーションの 64 ビット対応について解説しましたが、ASP.NET Web アプリケーションでは、一般に実行時コンパイルが行われるため、動作がちょっと複雑になります。これについて、以下に解説したいと思います。 なお、本エントリの解説は、すべて ASP.NET Web サイトプロジェクトによる Web アプリケーションを前提とします。VS2005 SP1 以降で導入された ASP.NET Web アプリケーションプロジェクトの場合には、一部のコードが先行コンパイルされる形になるため、本エントリの解説内容よりももう少し複雑になります。が、本エントリの内容と前回のエントリの内容を正しく理解すれば、スイッチの付与の仕方はわかると思いますので、このエントリでは Web アプリケーションプロジェクトについては解説対象外としたいと思います。 では、以下の順に解説していくことにします。 64 ビット/32 ビット動作の決定メカニズム Web サイトプロジェクトを含むソリューションのビルド構成設定 IIS 6 のワーカプロセスの動作ビットモードの変更方法 IIS 7 のワーカプロセスの動作ビットモードの変更方法 64 ビットワーカプロセスの制限事項 開発環境において 64 ビットワーカプロセスを使いたい場合について [Step. 11] ASP.NET Web アプリケーションの動作ビットの決定メカニズム まず、結論から記述すると、ASP.NET Web アプリケーションが64 ビット/32 ビットのどちらで動作するのかは、Web サーバのワーカプロセスの動作モードによって決定されます。 *.aspx ファイルや *.asmx ファイルは実行時に .dll ファイルにコンパイルされますが、これらのファイルはすべて Any CPU としてコンパイルされます。このため、この…

6

Silverlight 2 開発用 SDK の RTM 版

急に話が飛びますが、せっかくなので^^。昨日~今日にかけて、日本語用のSilverlight 2の開発用SDKがリリースされました。以下のセットでSilverlight 2 の開発環境がそろいます。 Visual Studio 2008 (Professional 以上) ※ SP1 を当ててください。 Expression Blend 2 ※ SP1 を当ててください。 http://www.microsoft.com/downloads/details.aspx?familyid=EB9B5C48-BA2B-4C39-A1C3-135C60BBBE66&displaylang=ja Visual Studio 2008 SP1 用 Microsoft Silverlight Tools http://www.microsoft.com/downloads/details.aspx?FamilyID=c22d6a7b-546f-4407-8ef6-d60c8ee221ed&DisplayLang=ja ※ このぺージの説明が一部 update されていませんが、これが正式リース版になっています。 Silverlight 2 ソフトウェア開発キット ドキュメント(オフラインでも読める製品ドキュメント) http://www.microsoft.com/downloads/details.aspx?FamilyID=bce7684a-507b-4fc6-bc99-6933cd690cab&DisplayLang=ja ようやくこれでツールセットが揃ったので早速インストール作業。今から Workshop のコンテンツの update 作業(β2→RTM)です。ComboBox、TabControlが追加されたのはかなり大きいポイントですね。

1

Part 2. .NET Framework 2.0 アプリケーションの 64 ビット対応

では引き続き、Part 2. のエントリでは、.NET Framework 2.0 のアプリケーションがどのようにして 64 ビット(または 32 ビット)で動作するのか、についてみていくことにします。.NET Framework では、IL (中間言語)と呼ばれるものが利用されているため、x86, x64, IA64 すべてに対応する .exe ファイルや .dll ファイルを作成することができます。にもかかわらず、Visual Studio を開くと、 ……と、こんなスイッチがあるわけなのですが、いったいこれは何なのか? これを理解するためには、.NET Framework のコンパイル動作を正しく把握する必要があります。これについて以下の手順で解説していくことにします。 IL コードとネイティブコード コンソールアプリケーションにおけるコンパイルスイッチの意味 ライブラリアプリケーションにおけるコンパイルスイッチの意味  [Step 7. IL コードとネイティブコード] .NET Framework の開発言語である C# や VB で書いたコードは、コンパイルしてもすぐに x86 や x64 などの命令コード(ネイティブコード)には変換されません。 .NET のアプリケーションコードはまずコンパイル時に MSIL (Microsoft Intermediate Language)と呼ばれる中間言語コードに変換されます。 そして実行時に CLR ランタイムがこれをネイティブコード(x86 や…

6