2017-10-21 7 views
2

私はLucene.Netベースの検索エンジンアプリケーションをC#で単一のインデックスで作成しています。要件として、複数のクエリを使用してテスト実行のランタイムを最適化する必要があります。したがって、検索ごとに別のスレッドを使用して、thisのような結果を返すことにしました。Lucene.Net Parallel Search

// load information needs 
List<InformationNeed> informationNeeds = FileReader.readInformationNeeds(collectionPath);    

// each search has its own thread referenced in this list 
List<Thread> threadList = new List<Thread>(); 

// each search has its own result referenced in this list 
List<SearchResult> searchResults = new List<SearchResult>(); 


foreach (InformationNeed informationNeed in informationNeeds){ 

    // create searchOptions 
    SearchOptions searchOptions = new SearchOptions(DEBUG_pre_processQuery, informationNeed.getInput()); 

    // run search 
    SearchResult result = null; // Used to store the return value 
    var thread = new Thread(
     () => 
     { 
     result = startSearch(searchOptions); 
     Console.WriteLine("end search for IN nr " + informationNeed.getID() + "results = " + result); 

     //add results to list 
     searchResults.Add(result); 

     }); 
    thread.Start(); 
    threadList.Add(thread); 
} 

// block main thread until all threads finished 
foreach (Thread t in threadList){ 
    t.Join(); 
} 

return searchResults; 

しかし、私は順次検索を実行し得ることはありませんLucene.Net.QueryParser.ParseException see screenshotを取得しています:私のコードは次のようになります。

私は何か不明な点をお伝えください。私はこの問題について助けていただければ幸いです。

+0

あなたは 'searchResults'へのアクセスを同期していません。それは問題を引き起こすだろう。 –

答えて

2

searchResultsへのアクセスを同期する必要があります。複数のスレッドで同時に変更する必要があります。または、非同期パターンを使用して、非同期メソッドからTask<SearchResult>を返し、すべてのスレッドに対して同じListを使用することはできません。

また、SearchResult resultをスレッド外に宣言すると、searchResultsが問題を引き起こしているのと同じ方法で問題を要求しています。スレッド内で宣言してください。

1

解決しました。 startSearchメソッドでは、hereのようにスレッドセーフではないQueryParserを呼び出しています。これを解決するには、lockQueryParserインスタンスに追加します。

+0

'searchResults'への非スレッドアクセスも修正しましたか? –

+0

はい私はまた、そこに 'ロック'を置く。ありがとうございました! – pad