我正在开发一个使用Lucene.net实现全文搜索的ASP.Net MVC 5应用程序。
由于ASP {Net中有potentional problems托管后台任务,我正在思考以下场景是否可行:
根本不使用FSDirectory吗?
答案 0 :(得分:0)
我认为这是可能的。您可以同时拥有多个IndexReader,它应该没问题,甚至还有一个外部锁定功能(基于文件系统),用于多进程锁定。
请记住,IndexReader将搜索当前的"快照"从创建时开始,你应该找到一种方法来转储"转储"索引更改时的IndexReaders。您当然可以为每次搜索创建一个IndexReader,但这可能不建议使用,如果您当前正在写入索引,则会失败。出于这些目的,你可以从当前作者中检索一个阅读器,但这不是一个选项,因为它们将驻留在不同的进程中。
您可能会发现这篇文章很有趣:
答案 1 :(得分:0)
在我为该项目编写的一个小助手类的帮助下,我设法让这个工作得很好。下面的工厂类共享一个具有任意数量线程的indexReader,并确保从GetCurrentReader()返回的读取器与索引的状态保持同步。
class IndexReaderFactory :
IDisposable
{
public IndexReaderFactory(bool isReadonly)
{
this.isReadonly = isReadonly;
}
IndexReader reader;
readonly ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();
private readonly bool isReadonly;
/// <summary>
/// Returns a reader that isCurrent
/// </summary>
public IndexReader GetUpToDateReader()
{
rwl.EnterUpgradeableReadLock();
try
{
if (reader == null)
{
rwl.EnterWriteLock();
try
{
if (logger.IsInfoEnabled)
logger.Info("Creating IndexReader on directory {0}", AppSettingsBase.LucenePostIndexLocation);
reader = IndexReader.Open(FSDirectory.Open(AppSettingsBase.LucenePostIndexLocation), isReadonly);
}
finally
{
rwl.ExitWriteLock();
}
}
else if(!reader.IsCurrent())
{
rwl.EnterWriteLock();
try
{
if (logger.IsInfoEnabled)
logger.Info("IndexReader is not current. Re-opening");
reader = reader.Reopen();
}
finally
{
rwl.ExitWriteLock();
}
}
}
finally
{
rwl.ExitUpgradeableReadLock();
}
return reader;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (disposing)
{
// get rid of managed resources
}
if(reader != null)
reader.Dispose();
}
}