[ 
https://issues.apache.org/jira/browse/LUCENENET-511?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13467587#comment-13467587
 ] 

Simon Svensson commented on LUCENENET-511:
------------------------------------------

In the scenario you described, where you only called IndexWriter.Dispose when 
isDisposing=true, your finalizer did not dispose of your IndexWriter. However, 
it was still finalized by the normal procedure of the garbage collector. The 
garbage collector, at the cleanup stage, has a list of objects that should be 
finalized, and will finalize them in a non-guaranteed order. Both your manager, 
and the IndexWriter class, will be finalized.

The FAQ simplifies the actual usage of the write.lock-file. It is used [by some 
locking strategies] to avoid concurrent modifications from other processes to 
the index, but it's up to the different strategies to define the details. The 
NativeFSLock calls FileStream.Lock (on a stream opened from write.lock) which 
means that no other process using NativeFSLock can do the same. It wont stop 
anyone from using Notepad, which have no clue about our locking mechanism, to 
modify index files at will.

There are several objects at work in your scenario. We've mentioned your 
manager, the IndexWriter and a NativeFSLock, but there's also a FileStream 
(which NativeFSLock creates and owns). I expect this to release the actual lock 
held when it's finalized, which means that another process can obtain the lock.

All this works as long as everyone agrees on using the same locking strategies. 
Nothing stops a slightly evil user to use a NoLock to wreak havoc in the index.
                
> ObjectDisposedException thrown when IndexWriter disposed by finalizer
> ---------------------------------------------------------------------
>
>                 Key: LUCENENET-511
>                 URL: https://issues.apache.org/jira/browse/LUCENENET-511
>             Project: Lucene.Net
>          Issue Type: Bug
>          Components: Lucene.Net Core
>    Affects Versions: Lucene.Net 3.0.3
>         Environment: Windows 7 x64, .NET Framework 4.5
>            Reporter: Maximilian Haru Raditya
>
> I'm having an issue of ObjectDisposedException with an error message "Cannot 
> access a closed file." when working IndexWriter.
> I manage to reproduce it when I create a new WPF (4.5) app and install 
> 3.0.3-RC2 from NuGet. I then create a LuceneManager which implements 
> IDisposable, and I create a finalizer for it. I wrap IndexWriter inside it, 
> and dispose it inside Dispose(bool). The implementation code looks like this:
> {code}
> namespace WpfApplication
> {
>     using System;
>     using System.Collections.Generic;
>     using System.IO;
>     using Lucene.Net.Analysis.Standard;
>     using Lucene.Net.Index;
>     using Lucene.Net.Store;
>     using Version = Lucene.Net.Util.Version;
>     public class LuceneManager : IDisposable
>     {
>         public static readonly string IndexPath =
>             Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Index");
>         private IndexWriter _indexWriter;
>         private bool _isDisposed;
>         public LuceneManager()
>         {
>             var directory = FSDirectory.Open(IndexPath);
>             var analyzer = new StandardAnalyzer(Version.LUCENE_30, new 
> HashSet<string>());
>             this._indexWriter = new IndexWriter(directory, analyzer, 
> IndexWriter.MaxFieldLength.UNLIMITED);
>         }
>         ~LuceneManager()
>         {
>             this.Dispose(false);
>         }
>         public void Dispose()
>         {
>             this.Dispose(true);
>             GC.SuppressFinalize(this);
>         }
>         private void Dispose(bool isDisposing)
>         {
>             if (!this._isDisposed)
>             {
>                 if (this._indexWriter != null)
>                 {
>                     this._indexWriter.Dispose();
>                 }
>                 this._indexWriter = null;
>                 this._isDisposed = true;
>             }
>         }
>     }
> }
> {code}
> And the calling code looks like this:
> {code}
> namespace WpfApplication
> {
>     using System.Windows;
>     public partial class MainWindow : Window
>     {
>         public MainWindow()
>         {
>             this.InitializeComponent();
>         }
>         private void OnLoaded(object sender, RoutedEventArgs e)
>         {
>             var lucenceManager = new LuceneManager();
>         }
>     }
> }
> {code}
> The app run just fine until I close it and it throws ObjectDisposedException 
> as described above.
> The exception details:
> {code}
> System.ObjectDisposedException was unhandled
>   HResult=-2146232798
>   Message=Cannot access a closed file.
>   Source=mscorlib
>   ObjectName=""
>   StackTrace:
>        at System.IO.__Error.FileNotOpen()
>        at System.IO.FileStream.get_Length()
>        at Lucene.Net.Store.NativeFSLock.Release()
>        at Lucene.Net.Index.IndexWriter.CloseInternal(Boolean waitForMerges)
>        at Lucene.Net.Index.IndexWriter.Dispose(Boolean disposing, Boolean 
> waitForMerges)
>        at Lucene.Net.Index.IndexWriter.Dispose(Boolean waitForMerges)
>        at Lucene.Net.Index.IndexWriter.Dispose()
>        at WpfApplication.LuceneManager.Dispose(Boolean isDisposing)
>        at WpfApplication.LuceneManager.Finalize()
>   InnerException: 
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to