Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 共享IEnumerable<;T>;和IQueryable<;T>;在多线程应用程序中_C#_Multithreading_Ienumerable_Iqueryable - Fatal编程技术网

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
    }
}