Search code examples
c#sqliteresharperwindows-store-appssqlite-net

Is the SQLiteConnection disposed inside of a Transaction?


This works, but Resharper says, "Access to disposed closure" on the commented line

using (var db = new SQLiteConnection(SQLitePath))
            {
                db.CreateTable<Locations>();

                db.RunInTransaction(() =>
                {
                    db.Insert(new Locations // Resharper: "Access to disposed closure" ???
                    {
                        PersonId = personId,
                        Latitude = latitude,
                        Longitude = longitude,
                        SentTimeUTC = sentTimeUTC,
                        ReceivedTimeLocal = receivedTimeLocal,
                        CivicAddress = civicAddress
                    });
                });
            }

This alternate approach also works, but with the same fingerwag from Resharper:

    var db = new SQLiteConnection(SQLitePath);
    {
        db.CreateTable<Locations>();

        db.RunInTransaction(() =>
        {
            db.Insert(new Locations // this works, although Resharper warns: "Access to disposed closure" ???
               {
                   PersonId = personId,
                      Latitude = latitude,
                      Longitude = longitude,
                      SentTimeUTC = sentTimeUTC,
                      ReceivedTimeLocal = ReceivedTimeLocal,
                      CivicAddress = civicAddress
               });
        });
    }
    db.Dispose();

They both work, so I guess it doesn't matter too much, but is one way preferable to the other? Is there a way to mollify Resharper and still get the job done?

UPDATE

What Donal said seemed sensible, yet I still get the Resharper "Potential Code Quality Issue" warning with this refactored code, on the Insert statement within the xaction:

public void InsertLocationRecord(string personId, double latitude, double longitude,
    DateTime sentTimeUTC, DateTime receivedTimeLocal, string civicAddress) 
{
    Locations locs = new Locations { PersonId = personId,
                                     Latitude = latitude,
                                     Longitude = longitude,
                                     SentTimeUTC = sentTimeUTC,
                                     ReceivedTimeLocal = receivedTimeLocal,
                                     CivicAddress = civicAddress
                                   };

    using (var db = new SQLiteConnection(SQLitePath))
    {
        db.CreateTable<Locations>();

        db.RunInTransaction(() =>
                                {
                                    db.Insert(locs); // Still get, "Access to disposed closure" on this line.
                                });
    }
}

Maybe I'm refactoring the problem in the wrong way? I guess this is not really much different than the previous way; how do I assure that the locs instance is disposed? Or is that not the issue here?


Solution

  • The problem is that you are creating a custom subclass of Locations in the middle there, which picks up all sorts of things that it doesn't need as part of the current context, and ReSharper is picking up on that (and isn't able to prove that it doesn't escape somehow). The easiest way to fix would actually be to add a constructor (or constructors, if necessary) to Locations to allow you to instantiate it with all the right values without closure capture.