有没有办法将任务并行库(TPL)与SQLDataReader一起使用?我喜欢TPL中Parallel.For和Parallel.ForEach扩展方法的简单性。我想知道是否有办法利用类似的东西,甚至是稍微更高级的任务。下面是一个SqlDataReader的典型用法,我想知道是否可以,如果可以,如何用TPL中的东西替换下面的while循环。因为读者无法提供固定的迭代次数,所以无法使用For扩展方法,而这将处理我将收集的任务。我希望有人可能已经解决了这个问题并使用ADO.net做了一些事情。使用(SqlConnectionconn=newSqlConnection("myConnString"))使用(SqlCommandcomm=newSqlCommand("myQuery",conn)){conn.Open();SqlDataReaderreader=comm.ExecuteReader();if(reader.HasRows){while(reader.Read()){//用Reader做点什么}}}你就快完成了。用这个签名包装你在函数中发布的代码:IEnumerableMyQuery()然后替换你的//DosomethingwithReader代码//DosomethingwithReader:yieldreturnreader;现在你有一些在单线程中工作的东西。不幸的是,当您读取查询结果时,它每次都会返回对同一个对象的引用,并且该对象只是在每次迭代时更改自身。这意味着如果您尝试并行运行它,您将得到一些非常奇怪的结果,因为并行读取可以更改不同线程中使用的对象。您需要代码来获取记录的副本以发送到并行循环。然而,在这一点上,我喜欢做的是跳过记录的额外副本,直接进入强类型类。更重要的是,我喜欢使用通用方法来执行此操作:IEnumerableGetData(Funcfactory,stringsql,ActionaddParameters){using(varcn=newSqlConnection("Myconnectionstring"))using(varcmd=newSqlCommand(sql,cn)){addParameters(cmd.Parameters);cn.打开();使用(varrdr=cmd.ExecuteReader()){while(rdr.Read()){yieldreturnfactory(rdr);}}}假设您的工厂方法按预期创建副本,则此代码在Parallel.ForEach循环中使用应该是安全的。调用该方法如下所示(假设Employee类具有名为“Create”的静态工厂方法):.Int).Value=50000;});Parallel.ForEach(UnderPaid,e=>e.GiveRaise());重要更新:我对这段代码没有以前那么自信了。单线程仍然可以改变读取器,而另一个线程正在执行复制。我可以锁定它,但我也担心另一个线程可能会在原始本身调用Read()之后但在开始复制之前调用更新读取器。所以这里的关键部分包含整个while循环...在这一点上,你回到了单线程。我希望有一种方法可以修改这段代码,使其在多线程场景中按预期工作,但还需要更多的研究。你将拥有很难直接替换while循环SqlDataReader不是线程安全类,所以你不能直接从多线程使用它。也就是说,您可以将TPL用于您读取的数据。这里有几个选项。最简单的方法是创建适合读者的IEnumerable实现并返回包含数据的类或结构。然后,您可以使用PLINQ或Parallel.ForEach语句处理数据Parallel.ForEach:publicIEnumerableReadData(){using(SqlConnectionconn=newSqlConnection("myConnString")))){conn.Open();SqlDataReaderreader=comm.ExecuteReader();if(reader.HasRows){while(reader.Read()){yieldreturnnewMyDataClass(...datafromreader...);一旦有了这个方法,就可以直接通过PLINQ或TPL对其进行处理:Parallel.ForEach(this.ReadData(),data=>{//在此处使用数据...});或者:以上是C#学习教程:IsthereawaytouseTaskParallelLibrary(TPL)withSQLDataReader?如果分享的内容对你有用,需要了解更多C#学习教程,希望你多多关注——this.ReadData().AsParallel().ForAll(data=>{//使用这里的数据...});本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
