Lucene.net对象的生命周期?

时间:2013-10-03 08:07:47

标签: lucene.net

我正在开发一个将在后台线程上运行的“索引服务”(作为WPF应用程序的一部分),并使用FileSystemWatcher来监视某些文件。当文件内容改变时,我想提取一些信息并更新Lucene索引。有时,用户可能希望对索引执行搜索。

每次用户执行搜索时,我是否应该创建索引阅读器?每次索引更新时都有作家?或者我的索引服务类(单例)是否可以使用单例读取器和编写器实例(加上单独的FSDirectory,它们都具有依赖性)?

如果我要使用单例实例,我是否需要担心关闭/处理它们?如果是,我的索引服务应该实现IDisposable,并在Dispose()中进行清理吗?

2 个答案:

答案 0 :(得分:1)

Lucene的InderWriterIndexReader实例都是线程安全的:您不应该将它们重新用作单例。初始化一个新实例非常昂贵(当为写入和搜索做出类似的设计选择时,显着改善,后者接近60%)。

对于IndexWriter,只需保留通过IndexingService公开的私有实例。对于IndexReader,您需要一种可以处理索引更改的不同方法。基于来源,你可以做到,

public class IndexingService

   ...

   public IndexReader GetReader()
   {
       var reopenedReader = this.reader.Reopen(openReadOnly: true);
       if (reopenedReader != this.reader) 
       {
           this.reader.Dispose(); 
           return this.reader = reopenedReader;
       }

       return this.reader;
   }

this.reader.Reopen的调用将首先检查读者是否是最新的(如果打开后没有发生任何变化),如果是,则它将自行返回。如果有更改,则阅读器将仅加载已更改的段,这通常比加载所有段更快。如果您希望多线程访问,还需要同步对阅读器的访问。

最后一件事:在应用程序关闭的情况下,你肯定需要处理资源,编写器和阅读器(使用Dispose()方法)。如果不这样做可能会破坏索引。

答案 1 :(得分:0)

每次创建一个编写器并不是最佳选择,因此您最好等待一段时间并编写所有更改。您可以在用户执行搜索时推送更改,这实际上取决于您的索引编写的复杂程度。

当您将更改提交到索引时,您需要创建一个新的索引阅读器,否则它将不会获取更改。所以我想将索引阅读器重新编入你的索引例程。但是,除非您更新索引,否则不要重新创建阅读器,因为这会降低您的应用程序速度。