1

这可行,但 Resharper在注释行上说“访问已处置的闭包”

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

这种替代方法也有效,但与 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();

它们都有效,所以我想这并不重要,但是一种方式比另一种方式更可取吗?有没有办法安抚 Resharper 并仍然完成工作?

更新

Donal 所说的似乎是明智的,但在 xaction 中的 Insert 语句中,我仍然收到 Resharper “潜在代码质量问题”的警告:

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

也许我以错误的方式重构问题?我想这与以前的方式并没有太大的不同;如何确保 locs 实例已处理?或者这不是这里的问题吗?

4

2 回答 2

1

问题是您Locations在中间创建了一个自定义子类,它会拾取作为当前上下文的一部分不需要的各种东西,而 ReSharper 正在接受这一点(并且无法证明它不会以某种方式逃脱)。最简单的修复方法实际上是添加一个构造函数(或多个构造函数,如果需要),Locations以允许您使用所有正确的值实例化它而无需捕获闭包。

于 2012-12-25T09:02:44.297 回答
1

第 1 步: 假设您的 Location 类中有这样的代码。

class Locations { 
    int PersonId;
    int Latitude;
    int Longitude;
    int SentTimeUTC;
    int ReceivedTimeLocal;
    int CivicAddress;

    // Functions;

    // {
    // Disposable resource
    // }
    public Locations (latitude,longitude,sentTimeUTC,receivedTimeLocal,civicAddress)
    {
        PersonId = personId;
        Latitude = latitude;
        Longitude = longitude;
        SentTimeUTC = sentTimeUTC;
        ReceivedTimeLocal = receivedTimeLocal;
        CivicAddress = civicAddress;
    };
};

像这样将您的课程更改为 IDisposable 课程。

class Locations : IDisposable { 
    int PersonId;
    int Latitude;
    int Longitude;
    int SentTimeUTC;
    int ReceivedTimeLocal;
    int CivicAddress;

    // Functions;

    // {
    // Disposable resource
    // }
    public Locations (latitude,longitude,sentTimeUTC,receivedTimeLocal,civicAddress)
    {
        PersonId = personId;
        Latitude = latitude;
        Longitude = longitude;
        SentTimeUTC = sentTimeUTC;
        ReceivedTimeLocal = receivedTimeLocal;
        CivicAddress = civicAddress;
    }

    public void Dispose() {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing) {
        if (disposing) {
            // Free your disposable resources here
            base.Dispose(disposing);
        }
    }
};

第2步: 然后将您的调用更改为原始代码

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

using (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.
        });
    }
}
于 2017-01-23T04:52:17.703 回答