由于原始线程(使用Linq to SQL的多线程)到现在已经很老了,我想我会在类似的主题上发布另一个问题。考虑一个方案,其中DomainService公开了许多方法来从SQL Server数据库检索数据。显然,在多用户方案中,同时有多个请求,人们必须期望this.DataContext可以并行使用,而开发人员无需控制也无需付出额外努力来处理这些多个请求。因此,如果我将顺序的LINQ查询放入Parallel.Invoke(),结果将彻底松开,然后我得到的内容 是“已经有与此命令关联的打开的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对象不是线程安全的对象。它期望由单个线程使用,而不是由多个并行线程使用。这是与数据读取器相关的一个例外,因为DataContext它的连接已打开,当您尝试并行执行第二条语句时,将与数据读取器一起读取。
如果您尝试在不使用SqlConnection任何序列化技术的情况下跨多个线程使用一个实例,则同样的问题将很明显。
SqlConnection