由于原始线程(Multi-threading with Linq to SQL)到现在已经很老了,我想我会针对类似的主题发布另一个问题。考虑一个方案,其中DomainService公开了许多方法来从SQL Server数据库检索数据。显然,在多用户方案中,同时有多个请求,人们必须期望this.DataContext可以并行使用,而开发人员无需控制也无需付出额外努力来处理这些多个请求。
因此,如果我将顺序的LINQ查询放入Parallel.Invoke(),结果将变得一团糟,并且我得到了删除的内容:“已经有与该Command相关联的打开的DataReader,必须首先关闭它。”错误 ...?
为了证明这一点,它可以工作:
List<Data> retVal = new List<Data>();
retVal.AddRange(this.DataContext.Table1.Where(w=>w.A==1).Select(s=>new Data{f1=s.D}).ToList());
retVal.AddRange(this.DataContext.Table1.Where(w=>w.B==2).Select(s=>new Data{f1=s.D}).ToList());
retVal.AddRange(this.DataContext.Table1.Where(w=>w.C==3).Select(s=>new Data{f1=s.D}).ToList());
...但是这不是:
List<Data> retVal = new List<Data>();
Parallel.Invoke(
()=>retVal.AddRange(this.DataContext.Table1.Where(w=>w.A==1).Select(s=>new Data{f1=s.D}).ToList()),
()=>retVal.AddRange(this.DataContext.Table1.Where(w=>w.B==2).Select(s=>new Data{f1=s.D}).ToList()),
()=>retVal.AddRange(this.DataContext.Table1.Where(w=>w.C==3).Select(s=>new Data{f1=s.D})).ToList());
不用担心,List不是线程安全的,因为错误来自SQL数据连接。
任何见解和解释将不胜感激。
请您参考如下方法:
首先,需要澄清的是,此问题与多线程而不是多用户有关。在多用户方案中,每个用户将拥有自己的DataContext实例,从而避免了共享实例周围的线程问题。
由于DataContext不是线程安全的对象,因此并行示例失败。它期望由单个线程使用,而不是由多个并行线程使用。这是与数据读取器相关的异常,因为DataContext的连接已打开,当您尝试并行执行第二条语句时,将与数据读取器一起读取。
如果您尝试在多个线程中使用一个SqlConnection实例而没有任何序列化技术,则同样的问题将很明显。




