private IEnumerable<int> PerformSearch(IList<SearchField> fields, Func<bool> isSearchCanceled)
{
var results = new HashSet<int>();
lock (m_syncRoot)
{
foreach (SearchField field in fields)
{
if (isSearchCanceled())
return null;
Tuple<int, int> key = IsFieldMultiString(field) ? Tuple.Create(field.Flid, field.String.get_WritingSystemAt(0)) : Tuple.Create(field.Flid, 0);
int pos;
if (!m_indexObjPos.TryGetValue(key, out pos))
{
pos = 0;
}
if (m_searchableObjs == null || pos < m_searchableObjs.Count)
{
// only use the IWorkerThreadReadHandler if we are executing on the worker thread
if (SynchronizationContext.Current == m_synchronizationContext)
{
pos = BuildIndex(pos, field, isSearchCanceled);
}
else
{
using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance<IWorkerThreadReadHandler>()))
pos = BuildIndex(pos, field, isSearchCanceled);
}
m_indexObjPos[key] = pos;
}
}
foreach (SearchField field in fields)
{
if (isSearchCanceled())
return null;
results.UnionWith(m_searcher.Search(field.Flid, field.String));
}
}
if (isSearchCanceled())
return null;
return results;
}