FirstChanceExceptionが無限ループに陥らないようにする実装方法

.Net 4.0 から導入された FirstChanceException イベントハンドラは、例外が発生した際に最初に例外が通知されるイベントです。(try catch よりも先に。)


但し、注意点としてFirstChanceExceptionイベントハンドラの中で新たに例外が発生するとFirstChanceExceptionが再帰的に呼び出されスタックオーバーフローしてしまうという問題があります。MSDNにはこの問題に対する対処としてCER(制約された実行領域)を使うことを推奨していますが、CERであっても例外が発生すれば再帰呼び出しされるので根本的な問題解決にはならないと思います。もちろん、CERなのでOutOfMemoryExceptionなどは防げると思います。


根本的な正しいアプローチとしては無限に再帰呼び出ししないようにすること。つまりFirstChanceException イベントハンドラを解除することです。


★★★★★★★★★★★★★★★★★★★★


まとめ


基本的には次の2つの対処を行えばよいと思います。

  1. 例外が発生しないようなコードを書くこと(大前提)
  2. FirstChanceExceptionのコードを実行する際にFirstChanceExceptionイベントハンドラの登録を解除すること。
using System;
using System.Windows.Forms;
using System.Diagnostics;

namespace WindowsFormsApplication1
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
      AppDomain.CurrentDomain.FirstChanceException += FirstChanceExHandler;
    }

    private void FirstChanceExHandler(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
    {

      try
      {
        AppDomain.CurrentDomain.FirstChanceException -= FirstChanceExHandler;

        try
        {
          throw new Exception("想定していない例外");
        }
        catch(Exception ex)
        {
          System.Diagnostics.Debug.WriteLine(ex.ToString());
        }

      }
      finally
      {
        AppDomain.CurrentDomain.FirstChanceException += FirstChanceExHandler;
      }

    }

  }
}