6

The exception is thrown up at times saying the file write.lock cannot be used as it is being used by another process, however this is a very simple test app for Lucene.Net and there's no other process using it, any idea of how this may be

The exception details are as follows:

System.IO.IOException was unhandled
HResult=-2147024864
Message=The process cannot access the file 
     'c:\temp\luceneidx\write.lock' because it is being used by another process.

Source=mscorlib
StackTrace:
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.File.InternalDelete(String path, Boolean checkHost)
    at System.IO.File.Delete(String path)
    at Lucene.Test.LuceneSearchInternal.get__directory() 
    in C:\Lucene.Test\LuceneSearchResumes.cs:line 35

The relevant code throwing the exception is,

var lockFilePath = Path.Combine(_luceneDir, "write.lock");

if (File.Exists(lockFilePath))
    File.Delete(lockFilePath);   // THROWS exception sometimes

The code is mostly from this article.

The index is being built on a background thread using Task.Factory.StartNew() and the WPF GUI does a search while the index is being built. There's only one thread writing documents to the index.

Question: Which other process is using the Lucene.Net index?

rae1
  • 6,066
  • 4
  • 27
  • 48
Kumar
  • 10,997
  • 13
  • 84
  • 134
  • Lucene.Net supports multiple threads so your background thread could be building the index while your WPF thread is searching (I think this is called "real-time" search). Even if you are not searching, the WPF thread may have opened the index before the background thread tries to delete the lock; this is one possible cause. – groverboy Feb 22 '13 at 00:00
  • @groverboy, if i comment out the line, File.Delete() the search works fine, so the question is - Is this necessary to call File.Delete() or is it that i have been lucky so far ? – Kumar Feb 22 '13 at 01:45
  • 1
    It is necessary to call `File.Delete`. This is part of a sanity-checking getter for an `FSDirectory` object; I think it checks for a lock file in case some process crashed earlier without unlocking the index. I haven't checked the CodeProject code but I presume it works and you have changed it. Probably the easiest fix is to ensure all threads (background thread, WPF thread) use the same `FSDirectory` object. – groverboy Feb 22 '13 at 02:05
  • yes, all threads do use the same FSDirectory object even with removing the File.Delete, however not really clear as to why there'd be an file in use by another process exception in this simple test case – Kumar Feb 22 '13 at 03:13
  • 1
    I just quickly read that CodeProject article, an this thing is full of fail. I'd definitely not refer to it to learn the basics of Lucene. It doesnt follow basic best practices like Document/Field instance re-use, it keeps closing IndexWriters/IndexSearchers, etc. – Jf Beaulac Feb 23 '13 at 19:56
  • @JfBeaulac I did a search for best practices but did not come across document/field/indexwriter/searcher instance re-use, any pointers on setting up multiple searchers and possibly multiple writers pls – Kumar Feb 24 '13 at 06:22
  • 1
    I agree with @JfBeaulac: you are better off learning from the original Lucene project which has already a lot of similarities both in concept and code to Lucene.Net. Check out [this tutorial](http://www.lucenetutorial.com/). – rae1 Mar 01 '13 at 14:24
  • 1
    the tutorial linked by @rae1n is a really good place to start. If you can, I'd also recommend to grab a copy of the book Lucene in action. It has everything you need to know + awesome code examples which are free to download: http://www.manning-source.com/books/hatcher2/LuceneInAction.zip – Jf Beaulac Mar 03 '13 at 04:19

1 Answers1

3

Assuming that the code presented is relevant to the search procedure (not the indexing procedure), you shouldn't try to delete the lock file every single time you try to access the index. The exceptions are being thrown because the background threads are currently writing to the index, and you are arbitrarily trying to delete its lock file when the thread itself should handle the deletion.

In the article you posted, this mechanism is used to recover the Lucene index after a system/application crash while it was writing the index, leaving it locked. However, this is hardly the common case. I believe that in the CodeProject article it is assumed a single-thread access to the index, hence the approach it takes.

In your project, you need to be able to check whether the existence of the lock file is due to current write access or to a previous application/system crash. You can use a lock object in your code, which is dynamically freed in the event of a crash, to discriminate between the two cases.

rae1
  • 6,066
  • 4
  • 27
  • 48