C# 共享IEnumerable<;T>;和IQueryable<;T>;在多线程应用程序中
对于在多线程应用程序中如何访问共享的C# 共享IEnumerable<;T>;和IQueryable<;T>;在多线程应用程序中,c#,multithreading,ienumerable,iqueryable,C#,Multithreading,Ienumerable,Iqueryable,对于在多线程应用程序中如何访问共享的IEnumerable和IQueryable,我几乎没有疑问 考虑这个代码片段 ObservableCollection<SessionFile> files = /* some code */ IEnumerable<Pattern> allFilePatterns= /*some query */ foreach (Pattern pattern in allFilePatterns) { string iclFilePat
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()
是异步的,这意味着所有SomeHandler
中的所有foreach
文件都将并行执行(每个文件都在其自己的线程中),那么IEnumerable
的共享实例是否会按预期/正常方式枚举?这是正确的方法吗?我可以在多个线程中共享同一个IEnumerable
实例,并并行枚举它吗
如果我在上面的代码中使用IQueryable
而不是IEnumerable
,会怎么样?有什么我应该注意的副作用吗
如果它不是线程安全的,那么我应该使用什么
请注意,我正在使用IQueryable
进行数据库查询,因为我不想从数据库中提取所有数据。因此,我希望尽量避免使用IQueryable.ToList()
我将ToList()
将枚举作为参数传递给委托,以实际创建一个新的集合供线程使用并避免问题
但是,我想知道为什么您需要将可枚举的每个元素枚举N次(实际上是N^2)?听起来效率很低
编辑:根据我的意图更新它取决于实现。
IEnumerable
的一些实现也实现了IEnumerator
,并从GetEnumerator()
返回它们自己。在这种情况下,它显然不是线程安全的
至于IQueryable
,这也取决于实现。例如,实体框架上下文不是线程安全的,只能在创建它们的线程上正常工作
所以这个问题没有唯一的答案。。。它可能适用于某些实现,而不适用于其他实现。查看和朋友
如果使用非线程安全的IQueryable(如实体框架查询),可以做的一件事是在一个线程中枚举结果,然后根据需要将结果传递给新线程
那么IQueryable/IEnumerable是否是线程安全的就无关紧要了。这仍然取决于SessionFile和Pattern的线程安全性
void SomeHandler(IEnumerable<Pattern> allFilePatterns)
{
foreach(Pattern pattern in allFilePatterns)
{
//some code
}
}