Estoy creando un sitio ASP.NET MVC donde deseo usar Lucene.Net para buscar. Ya he creado un SearchController y todos sus métodos, pero recibo un error en el tiempo de ejecución que ocurre cuando el SearchController se inicializa por primera vez.Error de bloqueo del directorio con el uso de Lucene.Net en un sitio MVC de ASP.NET
En SearchController, así es como estoy creando un 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);
El error se produce en la última línea. Este es el mensaje que estoy recibiendo:
Lucene.Net.Store.LockObtainFailedException: Lock obtener tiempo de espera: SimpleFSLock @ C: \ Users \ nombre de usuario \ Desktop \ SiteSolution \ Site \ Lucene \ escritura .lock
Además, aquí está el seguimiento de pila:
[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
¿Cómo puedo resolver este problema?
ACTUALIZACIÓN: He comenzado a trabajar en este proyecto en particular de nuevo, y parece que todavía no he resuelto este problema.
El problema real es que el archivo write.lock
no se elimina después de que finalice el uso del índice. En base a la respuesta que he aceptado, entiendo la lógica de implementación básica, pero no estoy seguro de haberla implementado correctamente. Aquí hay algunos otros métodos en mi clase que probablemente sean inválidos:
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);
}
¿Alguna idea?
¡Gracias por su respuesta! Mi IndexWriter estático nunca se cierra realmente ... ¿es eso un problema? –
@Maxim: la única razón por la que sería un problema es si varios procesos necesitan escribir. De lo contrario, generalmente es mejor mantener el escritor abierto y dejar que Lucene decida cuándo vaciar el disco. – Xodarap
@ Xodarap: He comenzado a trabajar de nuevo en este proyecto, y todavía no he resuelto el problema por completo. Estoy a punto de actualizar la pregunta con parte del código que estoy usando. Entiendo la lógica de implementación básica, pero no estoy seguro de haberlo implementado correctamente. –