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

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

Actually, that meant that the IndexWriter wasn't disposed by _your_ finalizer 
(destructor). The garbage collection will finalize (call the destructor) the 
IndexWriter, but it may happen either before or after your finalizer has 
executed. It's up the the nondeterministic nature of the garbage collection to 
surprise us when the IndexWriter is actually finalized.

The NativeFSLock (default lock for FSDirectory) does not depend on the mere 
existence of the write.lock file, it uses an exclusive lock using 
FileStream.Lock[1] to ensure a proper lock. A lingering write.lock file should 
not cause any problems.

This wouldn't be a problem if you implemented a deterministic approach to 
disposing your manager, simply by calling manager.Dispose() when closing the 
window. This would call Dispose(true), and your writer will be disposed, and 
the lock will be "cleanly" released.

[1] http://msdn.microsoft.com/en-us/library/system.io.filestream.lock.aspx
                
> 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