Multithreading Lucene.Net和I/O线程问题
我有一个名为“Execute()”的索引函数,它使用IndexWriter为我的站点内容编制索引。如果我只是在网页上调用它,效果会很好,但是当我将它作为委托参数放入System.Threading.Thread时失败了。奇怪的是,它总是在我的本地开发机器上工作,只有当我上传到共享主机时它才会失败 这是我收到的错误信息 “锁定获取超时:SimpleFSLock错误…” 下面是失败的代码(但仅在共享主机上失败) 下面是有效的代码(在我的本地计算机和共享主机上都有效) 现在,一些ppl说,这可能是上一次调试会话遗留下来的问题,所以在实例化IndexWriter之前,我做了Multithreading Lucene.Net和I/O线程问题,multithreading,lucene,lucene.net,Multithreading,Lucene,Lucene.net,我有一个名为“Execute()”的索引函数,它使用IndexWriter为我的站点内容编制索引。如果我只是在网页上调用它,效果会很好,但是当我将它作为委托参数放入System.Threading.Thread时失败了。奇怪的是,它总是在我的本地开发机器上工作,只有当我上传到共享主机时它才会失败 这是我收到的错误信息 “锁定获取超时:SimpleFSLock错误…” 下面是失败的代码(但仅在共享主机上失败) 下面是有效的代码(在我的本地计算机和共享主机上都有效) 现在,一些ppl说,这可能是上一
if (IndexReader.IsLocked(indexingFolder))
{
log.Debug("it is locked");
IndexReader.Unlock(FSDirectory.GetDirectory(indexingFolder));
}
else
{
log.Debug("it is not locked");
}
你猜怎么着?我的日志显示,它没有被锁定
所以现在我很确定这是由System.Thread.Threading引起的,但我只是不知道如何修复它
谢谢这可能是我没有使用lucene/shared hosting以来尝试回答这个问题的最糟糕的方法,但是SimpleFSLock听起来像是在文件系统上使用显式锁文件来锁定lucene索引文件(与锁定线程不同)。我要说的是检查以确保您配置了正确的文件路径,并且文件权限设置正确
否则,希望更熟悉Lucene.net的人能够回答。检查共享主机上的线程对索引文件夹的权限是否与开发机器/共享主机上的相同 更新:通过查询线程的
CurrentPrincipal
属性,可以找到线程运行的Principal
。虽然这是一个读写属性,但您可能没有在共享主机环境中设置此属性的权限
您可能会发现有帮助。我认为问题在于Lucene索引目录中的写锁文件。 去列出目录中的文件。 在Java Lucene中,您会在索引目录中看到一个名为write.lock的文件, 这意味着上次索引没有正确关闭(可能进程突然停止)。在Lucene.net中,查找类似名称的空文件。 我相信Lucene.net也会使用同样的机制。
尝试查找该文件,删除它并重新启动Lucene.net。谢谢大家,尤其是Vinay为我指明了正确的方向。经过多次追踪,我最终决定看一看源代码,看看有什么 在“IndexWriter”中,您有
Lock @lock = this.directory.MakeLock("write.lock");
if (!@lock.Obtain(this.writeLockTimeout))
它指向SimpleFSLock实现。罪魁祸首是
new FileStream(this.lockFile.FullName, FileMode.CreateNew).Close();
根据msdn,通过在内部创建新线程,它会抛出system.unauthorizedaccessexception
启动新线程时,System.Security.Principal.WindowsIdentity.GetCurrent()返回进程的标识,而不一定是调用thread.Start()的代码的标识。在模拟ASP.NET线程中启动异步委托或线程时,请务必记住这一点
如果您在ASP.NET中,并且希望新线程以模拟的WindowsIdentity开始,请将WindowsIdentity传递给ThreadStart方法。进入ThreadStart方法后,调用WindowsIdentity.Impersonate()
因此,我通过在“Execute()”函数中模拟运行我的应用程序的IIS帐户解决了我的问题,所有问题都得到了解决
再次感谢大家。谢谢凯文。文件路径是正确的,因为如果我只是通过不涉及线程来执行函数,那么一切都会按预期进行,索引正在创建,并且我能够搜索所有内容。一旦我将函数传递到Thread()构造函数中,它就会爆炸。ps:谢谢你在格式化方面帮助我:)嘿,维奈,我如何检查一个线程是否具有与我相同的权限?谢谢尤瓦尔。我刚刚运行了一个脚本,它打印了segments.gen segments_6_1.cfs就是这样。错误消息的细节确实表明了我的索引目录中“write.lock”的问题。但是,与上面显示的脚本结果一样,不存在“write.lock”文件。我已更新了我的答案,以将您提出的问题包含在您的评论中。表示感谢的正常方式是向上投票和/或接受答案:-)
Lock @lock = this.directory.MakeLock("write.lock");
if (!@lock.Obtain(this.writeLockTimeout))
new FileStream(this.lockFile.FullName, FileMode.CreateNew).Close();