У меня мало сомнений относительно того, как совместно используемые IEnumerable
и IQueryable
доступны в многопоточном приложении.
Рассмотрим этот фрагмент кода.
ObservableCollection<SessionFile> files = /* some code */
IEnumerable<Pattern> allFilePatterns= /*some query */
foreach (Pattern pattern in allFilePatterns)
{
string iclFilePath = Path.Combine(pattern.Location, pattern.Filename);
SessionFile sfile = new SessionFile(iclFilePath, pattern.AnalysisDate);
SomeDelegate invoker = new SomeDelegate(sfile.SomeHandler);
invoker.BeginInvoke(allFilePatterns, null, null);
files.Add(sfile );
}
Как видите, я использую BeginInvoke()
, передавая один и тот же экземпляр allFilePatterns
каждому обработчику с именем sfile.SomeHandler
.
Предположим, что в SomeHandler
я повторяю allFilePatterns в цикле foreach
, что-то вроде этого:
void SomeHandler(IEnumerable<Pattern> allFilePatterns)
{
foreach(Pattern pattern in allFilePatterns)
{
//some code
}
}
Теперь я сомневаюсь, что: поскольку BeginInvoke()
является асинхронным, это означает, что все foreach
во всех SomeHandler
всех файлов будут выполняться параллельно (каждый в своем собственном потоке), будет ли общий экземпляр IEnumerable
перечислить как ожидалось / нормально? Это правильный подход? Можно ли совместно использовать один и тот же экземпляр IEnumerable
в нескольких потоках и параллельно перечислять его?
А что если я использую IQueryable
вместо IEnumerable
в приведенном выше коде? Любой побочный эффект, о котором я должен знать?
Если это не потокобезопасно, то что мне использовать?
Обратите внимание, что я использую IQueryable
для запросов к базе данных, так как я не хочу извлекать все данные из базы данных. Поэтому я хочу максимально избежать IQueryable.ToList()
.