C# MaxMind GeoIP Reader Dispose问题-Reader.Dispose()之后的mmdb文件上的UnauthorizedAccessException

C# MaxMind GeoIP Reader Dispose问题-Reader.Dispose()之后的mmdb文件上的UnauthorizedAccessException,c#,geoip,maxmind,C#,Geoip,Maxmind,我正在使用MaxMind.Db.Reader类访问GeoLite2-City.mmdb文件,在调用读取器上的dispose后,在对文件执行某些操作时遇到文件访问问题 重现此问题的最简单方法是使用一个控制台应用程序,类似于MaxMind.Db.Benchmark项目,它有一个Reader类的静态实例,在我的例子中称为_cityReader 现在,如果您将_cityReader变量设置为读取器的新实例,然后对其调用dispose(我也将其设置为null),然后移动文件(移动工作正常),然后在文件的新

我正在使用MaxMind.Db.Reader类访问GeoLite2-City.mmdb文件,在调用读取器上的dispose后,在对文件执行某些操作时遇到文件访问问题

重现此问题的最简单方法是使用一个控制台应用程序,类似于MaxMind.Db.Benchmark项目,它有一个Reader类的静态实例,在我的例子中称为_cityReader

现在,如果您将_cityReader变量设置为读取器的新实例,然后对其调用dispose(我也将其设置为null),然后移动文件(移动工作正常),然后在文件的新位置调用delete,那么您将在删除操作中获得UnauthorizedAccessException

_cityReader = new Reader(@"C:\temp\MaxMind\Active\GeoLite2-City.mmdb", FileAccessMode.MemoryMapped);

_cityReader.Dispose();
_cityReader = null;

File.Move(@"C:\temp\MaxMind\Active\GeoLite2-City.mmdb", @"C:\temp\MaxMind\Active\GeoLite2-CityMoved.mmdb");
File.Delete(@"C:\temp\MaxMind\Active\GeoLite2-CityMoved.mmdb");
我发现,如果我使用反射调用Dispose _cityReader.\u stream.Value属性,那么在这个场景中,在调用_cityReader变量本身的Dispose之前,文件将删除

_cityReader = new Reader(@"C:\temp\MaxMind\Active\GeoLite2-City.mmdb", FileAccessMode.MemoryMapped);

FieldInfo field = typeof(Reader).GetField("_stream", BindingFlags.NonPublic | BindingFlags.Instance);
ThreadLocal<Stream> fieldValue = (ThreadLocal<Stream>)field.GetValue(_cityReader);
fieldValue.Value.Dispose();

_cityReader.Dispose();
_cityReader = null;

File.Move(@"C:\temp\MaxMind\Active\GeoLite2-City.mmdb", @"C:\temp\MaxMind\Active\GeoLite2-CityMoved.mmdb");
File.Delete(@"C:\temp\MaxMind\Active\GeoLite2-CityMoved.mmdb");
然后在控制台应用程序的主要方法中,我有这个

_cityReader = new Reader(@"C:\temp\MaxMind\Active\GeoLite2-City.mmdb", FileAccessMode.MemoryMapped);

Thread t = new Thread(DisposeReaderAndSwitchFiles);
t.Start();
t.Join();

Console.WriteLine("Press Any Key To Continue...");
Console.ReadKey();
这样代码示例就可以工作了,但是如果我从DisposereReaderAndSwitchFiles方法中删除GC.Collect()调用,就会得到UnauthorizedAccessException

是否有其他人在MaxMind.Db.Reader对象中遇到过类似问题

我是做错了什么还是应该做什么?强制垃圾收集感觉有点脏,如果可能的话我宁愿避免

谢谢


菲尔

我有一个问题与此不完全相同,但仍然是访问问题。你可以在这里找到它。

读卡器类内存在其Dispose方法中映射文件和内存映射文件。在您的问题中提到这一点可能会有所帮助,因为我怀疑这个问题通常与内存映射文件有关。(或者,您可以使用内存模式。)我不确定您的问题是否相关。当使用带有内存映射的C#API时,这个问题是一个文件访问问题,而您的问题似乎是Java API的类加载问题。
_cityReader = new Reader(@"C:\temp\MaxMind\Active\GeoLite2-City.mmdb", FileAccessMode.MemoryMapped);

Thread t = new Thread(DisposeReaderAndSwitchFiles);
t.Start();
t.Join();

Console.WriteLine("Press Any Key To Continue...");
Console.ReadKey();