使用Linq to SQL进行多线程 [英] Multi-threading with Linq to SQL

查看:82
本文介绍了使用Linq to SQL进行多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于原始线程(使用Linq to SQL的多线程)到现在已经很老了,所以我想我将在类似主题上发布另一个问题.考虑一个方案,其中DomainService公开了许多方法来从SQL Server数据库检索数据.显然,在多用户方案中,同时有多个请求,人们必须期望this.DataContext可以并行使用,而开发人员无需控制也无需付出额外努力来处理这些多个请求. 那么,如果我将顺序的LINQ查询放入Parallel.Invoke(),结果一切就变松了,我得到了重新填充的已经有一个与此命令相关联的打开的DataReader,必须首先关闭它." 错误...?

Since the original thread (Multi-threading with Linq to SQL) has become quite old by now, I've thought I'd post another question on a similar subject. Consider a scenario, where a DomainService exposes numerous methods to retrieve data from a SQL Server database. Obviously, in a multi user scenario, with multiple requests coming in at the same time, one has to expect this.DataContext to be used in parallel, with no control nor additional effort from the developer to handle those multiple requests. So how come, if I put my sequential LINQ queries into a Parallel.Invoke(), all hell breaks loose and I get the dreadded "There is already an open DataReader associated with this Command which must be closed first." error ...?

为了演示,这有效:

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数据连接.

Never mind for a second that List is not thread-safe, as the error is coming from the SQL data connection.

任何见解和解释将不胜感激.

Any insights and explanations will be much appreciated.

推荐答案

首先要澄清的是,此问题与多线程而不是多用户有关.在多用户方案中,每个用户将拥有自己的DataContext实例,从而避免了共享实例周围的线程问题.

First, to clarify, this issue is to do with multi-threading rather than multi-users. In a multi-user scenario, each user will have their own DataContext instance, avoiding threading issues around shared instances.

并行示例失败,因为DataContext不是线程安全的对象;它期望由单个线程使用,而不是由多个并行线程使用.这是与数据读取器相关的异常,因为DataContext的连接已打开,当您尝试并行执行第二条语句时,将与数据读取器一起读取.

The parallel example fails because the DataContext is not a thread-safe object; it expects to be used by a single thread, not by many in parallel. This emerges as an exception associated with data readers, because the DataContext has its connection open, reading with the data reader when you attempt to execute the second statement in parallel.

如果您尝试在多个线程中使用一个SqlConnection实例而没有任何序列化技术,则同样的问题将很明显.

The same issue would be evident if you tried to use one SqlConnection instance across several threads without any serialization techniques.

这篇关于使用Linq to SQL进行多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆