【发布时间】:2017-01-23 18:55:12
【问题描述】:
我正在使用 Lucene.Net 进行搜索,想知道如何处理这个线程问题。
我有一个Test类实例,但在这种情况下搜索器不是线程安全的,因为计时器线程可以在处理请求的同时更新索引,因此我确实看到了异常。关于如何使其线程安全的任何指针。
public class Test
{
private static object syncObj = new object();
private System.Threading.Timer timer;
private Searcher searcher;
private RAMDirectory idx = new RAMDirectory();
public Test()
{
this.timer = new System.Threading.Timer(this.Timer_Elapsed, null, TimeSpan.Zero, TimeSpan.FromMinutes(3));
}
private Searcher ESearcher
{
get
{
return this.searcher;
}
set
{
lock (syncObj)
{
this.searcher = value;
}
}
}
public Document CreateDocument(string title, string content)
{
Document doc = new Document();
doc.Add(new Field("A", title, Field.Store.YES, Field.Index.NO));
doc.Add(new Field("B", content, Field.Store.YES, Field.Index.ANALYZED));
return doc;
}
public List<Document> Search(Searcher searcher, string queryString)
{
List<Document> documents = new List<Document>();
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "B", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30));
Query query = parser.Parse(queryString);
int hitsPerPage = 5;
TopScoreDocCollector collector = TopScoreDocCollector.Create(2 * hitsPerPage, true);
this.ESearcher.Search(query, collector);
ScoreDoc[] hits = collector.TopDocs().ScoreDocs;
int hitCount = collector.TotalHits > 10 ? 10 : collector.TotalHits;
for (int i = 0; i < hitCount; i++)
{
ScoreDoc scoreDoc = hits[i];
int docId = scoreDoc.Doc;
float docScore = scoreDoc.Score;
Document doc = searcher.Doc(docId);
documents.Add(doc);
}
return documents;
}
private void Timer_Elapsed(object sender)
{
this.Log("Started Updating the Search Indexing");
// Get New data to Index
using (IndexWriter writer = new IndexWriter(this.idx, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30), true, IndexWriter.MaxFieldLength.LIMITED))
{
foreach (var e in es)
{
writer.AddDocument(this.CreateDocument(e.Value.ToString(), e.Key));
}
writer.Optimize();
}
this.ESearcher = new IndexSearcher(this.idx);
this.Log("Completed Updating the Search Indexing");
}
public Result ServeRequest()
{
var documents = this.Search(this.EntitySearcher, searchTerm);
//somelogic
return result;
}
}
【问题讨论】:
-
为什么要使用单实例开始?
-
在timer_elapsed中,关闭定时器,做工作,重新开启定时器
-
@CodeCaster ServiceFabric 将缓存实例,因此它将重用相同的索引。每次为新请求创建索引还有什么意义。
-
好吧,让我澄清一下:这段代码的哪一部分不是线程安全的?我怀疑
ESearcher你似乎在重用Searcher实例。 -
@CodeCaster timerThread 正在设置搜索器 (this.searcher = value;) 并且请求服务方法 (public Result ServeRequest()) 正在使用 this.ESearcher 进行搜索。
标签: c# multithreading search lucene.net