ObjectDisposedException は処理されませんでした。プログラム終了時にセーフハンドルがクローズされた

.NET 4 C#のコンソールアプリケーションを持っています。IBM iからデータを取り出し、インターネット上のSQLサーバーに送信します。それは終了するまで完璧に動作します、私は次のエラーを取得します。

System.ObjectDisposedException was unhandled Message=Safe handle has been closed. Source=mscorlib ObjectName="" StackTrace:

at System.Runtime.InteropServices.SafeHandle.DangerousRelease() at System.Threading.RegisteredWaitHandleSafe.Finalize() InnerException:

私のプログラムコードは

class Program
{
    static void Main(string[] args)
    {
        System.Console.WriteLine("Begin: " + DateTime.Now.ToString());
        SystemCodeController sc = new SystemCodeController();
        sc.SyncSystemCodes();
        ParkingTicketController pt = new ParkingTicketController();
        pt.SyncParkingTickets();
        EmailHelper.SendSuccessEmail();
        System.Console.WriteLine("End: " + DateTime.Now.ToString());
    }
}

コンソールには、開始時刻と終了時刻が表示されています。だから、最終行が実行されることは分かっています。私は何を忘れているか、または私がすべきことをやっていないのでしょうか?

Update:Sync* メソッドは IBM からデータをオブジェクトにプルし、エンティティフレームワークを使用してレコードをデータベースに挿入します。

public void SyncParkingTickets()
{
    ptr.ClearTable();
    ptr.InsertNewCitation(ibmI.GetAllCitations());
    ptr.SaveChanges();
}

public void InsertNewCitation(IEnumerable<ParkingTicket> citations)
{
    foreach (ParkingTicket citation in citations)
    {
        InsertNewCitation(citation);
    }
}

public void InsertNewCitation(ParkingTicket citation)
{
    db.AddToParkingTickets(citation);
}

public IEnumerable<ParkingTicket> GetAllCitations()
{
    SystemCodeRepository scr = new SystemCodeRepository();

    //  Create SQL statement

    DataTable dt = new DataTable();
    using (iDB2Connection conn = new iDB2Connection(_connString))
    {
        using (iDB2Command cmd = new iDB2Command(sb.ToString(), conn))
        {
            conn.Open();
            using (iDB2DataAdapter da = new iDB2DataAdapter(cmd)) { da.Fill(dt); }
            conn.Close();
        }
    }

    #region Fill object from DataTable
    var citations = from i in dt.AsEnumerable()
                    select new ParkingTicket
                    {
                        // Fill object
                    };
    #endregion

    return citations;
}

すべてのメソッドは、これと似たような動作をします。

ソリューション

データベースアクセスメソッドのiDB2Connectionファミリーを使用する際に同じエラーが発生するという報告]2を少し[ググってみると、いくつか散見されます。明らかに、IBMは.Net 1.1のEventHandlesの処理に依存しており、.Net 2.0への移行で変更されましたこのConnectの記事による

唯一の救済策は、IBMドライバーの最新バージョンに更新することです(5.3にはS21917サービスパック、5.4にはSI37892を使用してください)。


あなたは SafeWaitHandleClose()WaitHandle に対して呼び出していますか?

WaitHandle wh = ...;

wh.SafeWaitHandle.Close(); // will throw ObjectDisposedException

MSDNより

SafeWaitHandleプロパティに新しい値を代入すると、以前のSafeWaitHandleオブジェクトが回収されたときに、以前のハンドルが閉じられます。SafeWaitHandle がハンドルを閉じようとすると ObjectDisposedException が発生するため、手動でハンドルを閉じないでください。

解説 (4)

いずれかの型が Disposable になっていませんか?アプリケーションを終了する前に、すべてのディスポーザブルリソースを破棄してみてください。

解説 (3)

私も同じような状況です。問題は、SafeHandle.ReleaseHandleP/Invoke コールが何らかの魔法をかけて System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) を呼び出し、SafeHandle を破棄した後に何かをしようとする点です。

それは、あなた自身の SafeHandle の実装ではありませんね。そうでなければ、代わりに CriticalHandle を拡張してみることができたはずです。

解説 (2)