3

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

System.ObjectDisposedException 未处理 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());
    }
}

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

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

所有方法的操作都与此类似。

4

3 回答 3

7

在使用 iDB2Connection 系列数据库访问方法时,稍微搜索一下Google 就会发现一些关于相同错误的分散报告。显然,IBM 依赖 .Net 1.1 处理 EventHandles,根据这篇 Connect 文章,它在迁移到 .Net 2.0 时发生了变化。

似乎唯一的缓解办法是更新到最新版本的 IBM 驱动程序(如您所述,使用 5.3 的 S21917 服务包或 5.4 的 SI37892)。


你在打电话Close()吗?SafeWaitHandleWaitHandle

WaitHandle wh = ...;

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

来自 MSDN

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

于 2011-10-27T15:10:46.503 回答
2

您的任何类型都是一次性的吗?尝试在退出应用程序之前处置所有一次性资源。

于 2011-10-27T14:53:49.800 回答
0

我有一个平等的情况。那里的问题是P/Invokecall inSafeHandle.ReleaseHandle做了一些魔术和调用System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success),它试图SafeHandle在它被处理之后做一些事情。

它不是你自己的SafeHandle实现,不是吗?否则,您可以尝试扩展CriticalHandle

于 2011-10-27T15:02:17.207 回答