我正在构建一个ASP.NET MVC网站,我希望使用Lucene.Net进行搜索。我已经构建了一个SearchController及其所有方法,但是我在运行时遇到了一个错误,这个错误是在SearchController首次初始化时发生的。在ASP.NET MVC网站中使用Lucene.Net的目录锁定错误
在SearchController,这里是我如何创建一个IndexWriter类:在最后一行出现
public static string IndexLocation = HostingEnvironment.MapPath("~/lucene");
public static Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer();
public static IndexWriter writer = new IndexWriter(IndexLocation,analyzer);
错误。下面是我得到的消息:
Lucene.Net.Store.LockObtainFailedException: 锁定获取超时: SimpleFSLock @ C:\ Users \用户名\桌面\ SiteSolution \网站\ lucene的\写.lock
此外,这里的堆栈跟踪:
[LockObtainFailedException: Lock obtain timed out: [email protected]:\Users\Username\Desktop\SiteSolution\Site\lucene\write.lock]
Lucene.Net.Store.Lock.Obtain(Int64 lockWaitTimeout) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Store\Lock.cs:107
Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean create, Boolean closeDir, IndexDeletionPolicy deletionPolicy, Boolean autoCommit, Int32 maxFieldLength, IndexingChain indexingChain, IndexCommit commit) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Index\IndexWriter.cs:1827
Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean closeDir, IndexDeletionPolicy deletionPolicy, Boolean autoCommit, Int32 maxFieldLength, IndexingChain indexingChain, IndexCommit commit) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Index\IndexWriter.cs:1801
Lucene.Net.Index.IndexWriter..ctor(String path, Analyzer a) in C:\Users\Username\Desktop\Lucene.Net_2_9_2\src\Lucene.Net\Index\IndexWriter.cs:1350
Site.Controllers.SearchController..cctor() in C:\Users\Username\Desktop\SiteSolution\Site\Controllers\SearchController.cs:95
[TypeInitializationException: The type initializer for 'Site.Controllers.SearchController' threw an exception.]
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) +86
System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) +230
System.Activator.CreateInstance(Type type, Boolean nonPublic) +67
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
[InvalidOperationException: An error occurred when trying to create a controller of type 'Site.Controllers.SearchController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +190
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +68
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +118
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +46
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +63
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +13
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8682818
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
我怎样才能解决这个问题?
更新:我已经开始再次研究这个特定的项目,看来我还没有完全解决这个问题。
真正的问题是write.lock
文件在索引使用结束后未被删除。根据我接受的答案,我了解基本的实现逻辑,但我不确定是否已正确实施它。以下是我们班的其他一些方法可能无效:
public ActionResult Search(string query)
{
var reader = writer.GetReader(); // Get reader from writer
var searcher = new IndexSearcher(reader); // Build IndexSearch
//Execute search...
// Dispose of objects
searcher = null;
reader = null;
return View();
}
public void AddToIndex(Document doc)
{
writer.AddDocument(doc);
writer.Flush();
writer.Optimize();
writer.Flush();
}
private bool disposed = false;
protected override void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Release managed resources.
}
try
{
writer.Close();
writer = null;
}
catch
{
}
// Release unmanaged resources.
// Set large fields to null.
// Call Dispose on your base class.
disposed = true;
}
base.Dispose(disposing);
}
有什么想法?
感谢您的回答!我的静态IndexWriter从来没有真正关闭......这是一个问题吗? – 2010-11-25 06:49:22
@Maxim:如果多个进程需要编写,将是一个问题的唯一原因。否则,通常最好让作者保持打开状态,让lucene决定何时刷新到磁盘。 – Xodarap 2010-11-25 22:48:22
@ Xodarap:我已经开始重新研究这个项目,但我仍然没有完全解决这个问题。我即将更新与我正在使用的一些代码的问题。我了解基本的实现逻辑,但我不确定是否已正确实施。 – 2011-02-19 01:17:39