由于原始线程(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实例而没有任何序列化技术,则同样的问题将很明显。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!