Domanda

I have a .NET 4 C# console application. It pulls data from our IBM i and sends it to our internet SQL Server. It works perfect until it ends, I get the following error:

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:

My program code is:

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());
    }
}

In the console, I see the begin time and the end time. So I know the final line does get executed. What am I forgetting or not doing that I should be?

Update: The Sync* methods pull data from the IBM into an object then uses entity framework to insert the records into the database.

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;
}

All of the methods operate similar to this one.

È stato utile?

Soluzione

A little bit of Googling reveals some scattered reports of the same error when using the iDB2Connection family of database access methods. Evidently IBM is relying on .Net 1.1 handling of EventHandles which changed in the move to .Net 2.0 per this Connect article.

It seems the only reprieve is to update to the latest version of the IBM drivers (using the S21917 service pack for 5.3 or SI37892 for 5.4 as you note).


Are you calling Close() on the SafeWaitHandle for a WaitHandle?

WaitHandle wh = ...;

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

From MSDN:

When you assign a new value to the SafeWaitHandle property, the previous handle will be closed when the previous SafeWaitHandle object is collected. Do not manually close the handle, because this results in an ObjectDisposedException when the SafeWaitHandle attempts to close the handle.

Altri suggerimenti

Are any of your types Disposable? Try disposing all of your disposable resources before exiting the application.

I have an equal situation. The problem there is that a P/Invoke call in SafeHandle.ReleaseHandle does some magic and calls System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success), which tries to do something with the SafeHandle after it was disposed.

Its not your own SafeHandle implementation isn't it? Otherwise you could have tried extending CriticalHandle instead.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top