Индексирование документов Lucene.Net Parallel.ForEach - ошибка «Ссылка на объект» - PullRequest
0 голосов
/ 15 октября 2018

Я использую Lucene.Net для индексации файлов на различных дисках.Я прочитал, что IndexWriter является потокобезопасным, и подумал, что я могу ускорить «чтение» документа и запись его в индекс с помощью цикла Parallel.ForEach, но я продолжаю получать ссылку на объект, не установленную вслучайное появление ошибки объекта, заставляющее меня думать, что то, что я делаю, не является поточно-ориентированным, хотя я использую проверку нуля, чтобы убедиться, что объект не равен нулю, прежде чем добавить его в модуль записи.Вот код;какие-либо указатели или мысли о том, что может быть причиной этой ошибки?Я отметил это в коде ниже - он находится в строке CreateDocument ().

public class LuceneIndexService : LuceneService
{

    private IndexWriter writer;
    private IndexWriterConfig config;

    public LuceneIndexService(string _indexLocation) : base(_indexLocation)
    {
        config = new IndexWriterConfig(Lucene.Net.Util.LuceneVersion.LUCENE_48, analyzer);
        writer = new IndexWriter(luceneIndexDirectory, config);
    }

    public void CreateIndex(List<string> filesToIndex, BackgroundWorker bgWorker)
    {
        // Background worker is passed to report progress
        BackgroundWorker bgWorkerToReportTo = bgWorker;
        int fileCount = filesToIndex.Count;
        int progressCount = 0;

        // Writing files to index
        Parallel.ForEach(filesToIndex, (filepath) =>
        {
            FileData documentData = FileReader.GetDataFromFile(filepath);
            //null check
            if (documentData == null || documentData.content == null || documentData.filepath == null || documentData.filesize == null)
                Console.WriteLine(filepath + " IS NULL");
            else
            {
                // ** This is where I get the error **
                CreateDocument(documentData);
            }

            // Reporting progress so progress bar can be updated
            int percentage = (Interlocked.Increment(ref progressCount)) * 100 / fileCount;
            bgWorkerToReportTo.ReportProgress(percentage);
        });

        writer.Flush(true, true);
        writer.Dispose();
    }

    private void CreateDocument(FileData data)
    {
        Document document = new Document();
        document.AddTextField("content", data.content, Field.Store.YES);
        document.AddStringField("filepath", data.filepath, Field.Store.YES);
        document.AddStringField("filesize", data.filesize, Field.Store.YES);

        writer.AddDocument(document);
    }
}

Это абстрактный класс, от которого наследуется вышеуказанный класс - он просто объявляет общий анализатор, который могут использовать несколько классов (писатель, поисковик и т. Д.), И «открывает» каталог.

public abstract class LuceneService
{
    internal Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.LuceneVersion.LUCENE_48);
    internal Directory luceneIndexDirectory;
    internal string IndexLocation;

    public LuceneService(string _indexLocation)
    {
        IndexLocation = _indexLocation;
        luceneIndexDirectory = FSDirectory.Open(_indexLocation);
    }
}
...