Lucene.Net和I / O线程问题

时间:2009-07-14 05:02:32

标签: multithreading lucene lucene.net

我有一个名为“Execute()”的索引函数,使用IndexWriter索引我网站的内容。如果我只是从网页上调用它,它的效果很好,但是当我将它作为委托参数输入System.Threading.Thread时失败了。奇怪的是,它总是在我的本地开发机器上工作,它只在我上传到共享主机时失败。

这是我收到的错误消息

“Lock获取超时:SimpleFSLock错误....”

以下是失败的代码(但仅在共享主机上失败)

Scheduler scheduler = new Scheduler();
System.Threading.Thread schedulerThread = new System.Threading.Thread(scheduler.Execute);

以下是有效的代码(在本地计算机和共享主机上都可以使用)

Scheduler scheduler = new Scheduler();
schedulre.Execute();

现在,一些ppl说,它可能是以前的调试会话遗留下来的一个坏的,所以在我实例化IndexWriter之前,我做了

if (IndexReader.IsLocked(indexingFolder))
{

    log.Debug("it is locked");
    IndexReader.Unlock(FSDirectory.GetDirectory(indexingFolder));
}
else
{
    log.Debug("it is not locked");
}

并猜猜是什么?我的日志说,它没有锁定。

所以现在我很确定它是由System.Thread.Threading造成的,但我不知道如何修复它。

由于

4 个答案:

答案 0 :(得分:4)

检查共享主机上的线程是否与开发计算机/共享主机上的索引文件夹具有相同的权限。

更新:您可以通过询问线程的Principal属性找到线程正在运行的CurrentPrincipal。虽然这是一个读写属性,但您可能没有权限在共享主机环境中设置此属性。

您可能会发现this post有帮助。

答案 1 :(得分:2)

感谢大家,尤其感谢Vinay指出我正确的方向。经过大量追踪后,我终于决定查看源代码并查看其中的内容。

在“IndexWriter”中,你有

  Lock @lock = this.directory.MakeLock("write.lock");
  if (!@lock.Obtain(this.writeLockTimeout))

指向SimpleFSLock实现。罪魁祸首是

new FileStream(this.lockFile.FullName, FileMode.CreateNew).Close();

通过在内部创建一个新线程,它会抛出一个system.unauthorizedaccessexception,根据msdn here

  

启动新线程时,System.Security.Principal.WindowsIdentity.GetCurrent()返回进程的标识,不一定是调用Thread.Start()的代码的标识。在模拟的ASP.NET线程中启动异步委托或线程时,这一点很重要。

     

如果您在ASP.NET中并希望新线程以模拟的WindowsIdentity开头,请将WindowsIdentity传递给ThreadStart方法。进入ThreadStart方法后,调用WindowsIdentity.Impersonate()。

这样,我通过在“执行()”函数中模拟运行我的应用程序的IIS帐户解决了我的问题,并解决了所有问题。

再次感谢所有人。

答案 2 :(得分:0)

可能是最糟糕的一个尝试回答这个,因为我没有使用lucene /共享主机,但SimpleFSLock听起来像是通过在文件系统上使用显式锁文件锁定lucene索引文件(与锁定不完全相同)在线程)。我会说检查以确保您已配置正确的文件路径并且文件权限设置正确。

否则,希望更熟悉Lucene.net的人可以回答。

答案 3 :(得分:0)

我认为问题在于Lucene索引目录中的写锁文件。 转到并列出目录的文件。 在Java Lucene中,你会在索引目录中看到一个名为write.lock的文件, 这意味着上次索引没有正确关闭(可能是一个过程突然停止)。在Lucene.net中,查找类似命名的空文件。 我相信Lucene.net会使用相同的机制。 尝试找到该文件,删除它并重新启动Lucene.net。