.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を使用してください)。
あなたは SafeWaitHandle
で Close()
を WaitHandle
に対して呼び出していますか?
WaitHandle wh = ...;
wh.SafeWaitHandle.Close(); // will throw ObjectDisposedException
SafeWaitHandleプロパティに新しい値を代入すると、以前のSafeWaitHandleオブジェクトが回収されたときに、以前のハンドルが閉じられます。SafeWaitHandle がハンドルを閉じようとすると ObjectDisposedException が発生するため、手動でハンドルを閉じないでください。
私も同じような状況です。問題は、SafeHandle.ReleaseHandle
の P/Invoke
コールが何らかの魔法をかけて System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
を呼び出し、SafeHandle
を破棄した後に何かをしようとする点です。
それは、あなた自身の SafeHandle
の実装ではありませんね。そうでなければ、代わりに CriticalHandle
を拡張してみることができたはずです。