SHOEISHA iD

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

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

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

japan.internet.com翻訳記事

ASP.NET 2.0のHTTPハンドラ(*.ashx)をデバッグする

System.Diagnostics名前空間のクラスによるHTTPハンドラのデバッグ

デバッグビルドでのデバッグ

 デバッグビルドを使用するときは、Visual Studioデバッガのすべてのリソース、すべての.NET Framework名前空間、およびすべてのユーティリティとアプリケーションを利用できます。Visual Studioデバッガでは、コールスタック、ローカル変数、ウォッチ変数などを確認できます。読者の皆さんは、これらの機能にある程度は精通していることでしょう。しかし、HTTPハンドラの場合、デバッグはこれまで以上に重要です。それは、目に見える形で現れるバグは、すべてコンテンツにコーディングした内容であるためです。

リリースビルドでのデバッグ

 リリースビルドは、機能とパフォーマンスの両方の面でデバッグビルドとは異なります。リリースビルドを使用しているときは、おそらく運用環境にあります。そのような場合は、異なるツールセットを使用して問題箇所を見つける必要があります。

System.Diagnostics名前空間によるデバッグ

 Diagnostics名前空間には、リリースモードとデバッグモードでのデバッグに役立つクラスが数多く用意されています。リリースモードでデバッグする場合は、Traceクラスを使用します。デバッグモードでデバッグする場合は、Assertクラスを使用します。本稿では、この名前空間のすべての機能を取り上げるわけではありませんので、当面の問題解決に役立つクラスは各自で調べてください。

 これらのクラスの使い方を理解するために、この名前空間を使用して、無限ループを使用するようにコードを変更してみましょう。アサーション内の式がfalseのときにエラーがスローされるので、以下の例ではカウンタが10に達するとエラーがスローされます。

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Web.SessionState;
using System.Diagnostics;

public class Handler : IHttpHandler , IReadOnlySessionState{

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/html";
        context.Response.Write("Hello World");

        int i=0;

        while (1!=0)
        {
            Debug.Assert(i<10);
            i++;
        }

    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

 ビルドとデバッグを行ってみましょう。ブレークポイントが設定されていないため、アサーションがヒットするとデバッガが再びアクティブになります。発見しようとするエラーがあらかじめ分かっていて、それをテストできる場合には、この方法が適しています。まずアサーションウィンドウが表示され、アサーションに関する情報が表示されます。デバッガをアクティブにしたい場合は、[Retry]ボタンをクリックします。これによりデバッガが表示され、問題のアサーションコード行が示されます。

 特定のBoolean文でテストするのではなく、おおまかなコード位置を調べたい場合は、コード内でDebugger.Break文を使用します。この場合も、デバッガが表示されます。前提条件を調べ、なおかつエラーで停止する場合は、この2つの文を組み合わせることで、デバッグのプロセスを効率化することができます。このコードの例を以下に示します。

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Web.SessionState;
using System.Diagnostics;

public class Handler : IHttpHandler , IReadOnlySessionState{

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/html";
        context.Response.Write("Hello World");

        Debugger.Break();

        int i=0;

        while (1!=0)
        {
            Debug.Assert(i<10);
            i++;
        }
    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

 デバッグセッションの中で、Debug.WriteDebug.WriteIfDebug.WriteLine、およびDebug.WriteLineIfを使用すると、出力ウィンドウに値を書き出すことができます。これは、HTTPハンドラの状態を表示するのに役立ちます。

 リリースビルドで問題の原因を突き止めるには、コードを調べる手段が必要です。1つの方法は、コードにEventLog.WriteEntry文を追加することです。これによって、HTTPハンドラの実行時にイベントログに情報を追加することができます。WriteEntryメソッドは非常に負荷がかかるため、各自の環境に適した最善の方法を判断する必要があります。イベントビューアに単純な情報エントリが表示されるようにするには、WriteEntryメソッドに1つのString引数を指定します。イベントビューアはイベントの「ソース」についての情報を要求するので、これを「HTTPHandler-DebugArticle」と名付けます。これにより、イベントビューアで簡単に確認できるようになります。コードは次のようになります。

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Web.SessionState;
using System.Diagnostics;

public class Handler : IHttpHandler , IReadOnlySessionState{

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/html";
        context.Response.Write("Hello World");

        int i=0;

        // Create an EventLog instance and assign its source.
        EventLog myLog = new EventLog();
        myLog.Source = "HTTPHandler-DebugArticle";

        while (i<100)
        {
            if (i/10==0)
            {
                // Write an informational entry to the event log.
                myLog.WriteEntry("Writing to event log: i is divisible by 10.");
            }
            i++;
        }

    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

 ハンドラのリリースバージョンをビルドし、実際に呼び出してみましょう。出力には、「Hello World」というテキストだけが含まれます。それではイベントビューアを開き、アプリケーションログを開いてください。「HTTPHandler-DebugArticle」というソースからの多くの情報が表示されます。

 このうちいずれかのイベントを開くと、簡単な出力が表示されます。

 System.Diagnostics名前空間には、パフォーマンスモニタと連携するクラスや、ロジックフローのデバッグに役立つプロセスやクラスもあります。

プロセスにアタッチして実行中のHTTPハンドラをデバッグする

 問題箇所を見つけるもう1つの方法として、HTTPハンドラを含むプロセスにアタッチする方法があります。複数のWebサイトを実行していて、各Webサイトがそれぞれ独自のプロセス空間にある場合は、プロセスIDを判別しなければならない可能性があります。ハンドラにこれを指定させるのが、最も簡単な方法です。System.Diagnostics名前空間にはProcessというクラスがあり、現在のプロセスIDを判断するのに役立ちます。IDを見つけるには、コードを次のように変更することで、イベントビューアにIDを送ります。

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Web.SessionState;
using System.Diagnostics;

public class Handler : IHttpHandler , IReadOnlySessionState{

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/html";
        context.Response.Write("Hello World");

        int i=0;

        Process.GetCurrentProcess().Id.ToString();

        // Create an EventLog instance and assign its source.
        EventLog myLog = new EventLog();
        myLog.Source = "HTTPHandler-DebugArticle";
        myLog.WriteEntry("Process Id is " + Process.GetCurrentProcess().Id.ToString());

        while (i<100)
        {
            if (i/10==0)
            {
                // Write an informational entry to the event log.
                myLog.WriteEntry("Writing to event log: i is divisible by 10.");
            }
            i++;
        }

    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

 ここで重要なコード行は、ループ内のコード行と、myLog.WriteEntry:Process.GetCurrentProcess().Id内の文字列を置き換えるコード行です。次の図は、イベントビューアのエントリの例を示しています。

 プロセスIDが分かったら、このIDをタスクマネージャで探す必要があります。タスクマネージャでプロセスIDを探すには、[プロセス]タブをクリックし、[表示]をクリックして、[列の選択]を選択します。[PID(プロセスID)]チェックボックスをオンにし、[OK]をクリックしてダイアログを閉じます。プロセスのリストに[PID]列が表示されるので、列名をクリックしてソートできます。リスト内で目的のプロセスIDを見つけたら、これを右クリックし、[デバッグ]を選択します。これによってVisual Studioが開始します。Visual Studioからコードファイルを開き、そこでデバッグを行います。

まとめ

 ASP.NET HTTPハンドラは単純なクラスであり、これを使用することで要求を処理し、ブラウザに応答を返すことができます。ハンドラによって、現在のWebコンテキストとセッションステートにアクセスできます。Visual Studio 2005で提供される既定の「Generic Handler」は、現在のコードでは動作しない可能性があります。いくつかの変更を加え、System.Diagnostics空間と連携することで、ビルドとデバッグが正しく行われるHTTPハンドラを作成することができます。

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

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

もっと読む

この記事の著者

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

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

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

Dina Fleet Berry(Dina Fleet Berry)

.NETプログラマ、テクニカルライター。Project 31Aプログラミングブログに寄稿。

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/476 2006/08/22 15:51

イベント

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

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

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

メールバックナンバー