关于多线程应用程序中如何访问共享的 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
中,我使用foreach
循环遍历allFilePatterns,像这样:
void SomeHandler(IEnumerable<Pattern> allFilePatterns)
{
foreach(Pattern pattern in allFilePatterns)
{
//some code
}
}
现在我的疑惑是:由于
BeginInvoke()
是异步的,这意味着所有文件中SomeHandler
中的所有foreach
都会并行执行(每个在自己的线程中),此时共享的IEnumerable
实例是否会按预期/正常的方式进行枚举?这种方法正确吗?我可以在多个线程中共享同一个IEnumerable
实例,并并行枚举它吗?如果我在上面的代码中使用
IQueryable
而不是IEnumerable
会发生什么?我应该注意哪些副作用?如果它不是线程安全的,那么我应该使用什么?
请注意,我正在使用
IQueryable
进行数据库查询,因为我不想从数据库中拉取所有数据。因此,我希望尽可能避免使用IQueryable.ToList()
。