ObjectDisposedException未处理:安全句柄已在程序结束时关闭

时间:2011-10-27 14:50:19

标签: c# .net-4.0 console-application objectdisposedexception

我有一个.NET 4 C#控制台应用程序。它从我们的IBM i中提取数据并将其发送到我们的Internet SQL Server。它完美无缺,直到它结束,我得到以下错误:

  

System.ObjectDisposedException未处理Message = Safe句柄   已关闭Source = mscorlib ObjectName =“”StackTrace:          在System.Runtime.InteropServices.SafeHandle.DangerousRelease()          在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());
    }
}

在控制台中,我看到了开始时间和结束时间。所以我知道最后一行确实被执行了。我应该忘记或不做的是什么?

更新: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;
}

所有方法都与此类似。

3 个答案:

答案 0 :(得分:7)

使用iDB2Connection系列数据库访问方法时,有一点Googling reveals some scattered reports的相同错误。显然,IBM依赖于.Net 1.1处理EventHandles,后者在迁移到.Net 2.0 per this Connect article时发生了变化。

似乎唯一的缓解是更新到最新版本的IBM驱动程序(使用适用于5.3的S21917服务包或适用于5.4的SI37892)。


您是否在Close()上为SafeWaitHandle致电WaitHandle了?

WaitHandle wh = ...;

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

From MSDN

  

为SafeWaitHandle属性分配新值时,前一个句柄将在收集前一个SafeWaitHandle对象时关闭。不要手动关闭句柄,因为当SafeWaitHandle尝试关闭句柄时会导致ObjectDisposedException。

答案 1 :(得分:2)

您的任何类型Disposable都是?在退出应用程序之前,请尝试处理所有可支配资源。

答案 2 :(得分:0)

我的情况相同。问题在于,P/Invoke中的SafeHandle.ReleaseHandle电话会产生一些魔力,并会调用System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)SafeHandle会在SafeHandle处理之后尝试对其进行操作。

不是你自己的CriticalHandle实现不是吗?否则,您可能已尝试扩展{{1}}。