Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据读取器结果的并发处理_C#_Multithreading_Datareader - Fatal编程技术网

C# 数据读取器结果的并发处理

C# 数据读取器结果的并发处理,c#,multithreading,datareader,C#,Multithreading,Datareader,我的目标是在读取从Datareader返回的结果时获得更好的性能。下面的例子可以更好地理解这个问题。 我们假设有10个结果集是从datareader返回的。当我们循环这些记录来填充我们的对象时,所花费的总时间约为3秒。现在有人问我如何在1秒以下完成 这可以通过在datareader中同时处理读取操作来实现吗?如果是,我们怎么做 IDataAccessMapper _dataAccessMapper; var query = new StringBuilder(); query.Append("

我的目标是在读取从Datareader返回的结果时获得更好的性能。下面的例子可以更好地理解这个问题。 我们假设有10个结果集是从datareader返回的。当我们循环这些记录来填充我们的对象时,所花费的总时间约为3秒。现在有人问我如何在1秒以下完成

这可以通过在datareader中同时处理读取操作来实现吗?如果是,我们怎么做

IDataAccessMapper _dataAccessMapper;

var query = new StringBuilder();
query.Append("SELECT * FROM Step01");
query.Append("SELECT * FROM Step02");
query.Append("SELECT * FROM Step03");
......
query.Append("SELECT * FROM Step10");
var selCommand = dbContracts.GetTextCommand(query.ToString());
var dataReader = selCommand.AsReader();
while (dataReader.Read()){
    //Do something
}

var step1Details = new Collection<Step1Details>
if (dataReader.NextResult()){
    _dataAccessMapper.MapRecords<Step1Details>(dataReader, step1Details);
}
var step2Details = new Collection<Step2Details>
if (dataReader.NextResult()){
    _dataAccessMapper.MapRecords<Step2Details>(dataReader, step2Details);
}
....
....
var step10Details = new Collection<Step10Details>
if (dataReader.NextResult()){
    _dataAccessMapper.MapRecords<Step10Details>(dataReader, step10Details);
}
....
IDataAccessMapper\u dataAccessMapper;
var query=new StringBuilder();
query.Append(“SELECT*FROM Step01”);
query.Append(“从步骤02中选择*);
query.Append(“从步骤03中选择*);
......
query.Append(“从步骤10中选择*);
var selCommand=dbContracts.GetTextCommand(query.ToString());
var dataReader=selCommand.AsReader();
while(dataReader.Read()){
//做点什么
}
var step1Details=新集合
if(dataReader.NextResult()){
_映射记录(dataReader,step1Details);
}
var step2Details=新集合
if(dataReader.NextResult()){
_映射记录(dataReader,step2Details);
}
....
....
var step10Details=新集合
if(dataReader.NextResult()){
_映射记录(dataReader,步骤10详细信息);
}
....

DataReader不能保证线程安全,尽管我认为问题源于连接类,它不是线程安全的。您可以做的是运行单独的线程(使用它们自己的连接)来执行单独的select语句并同时处理数据。这还将确保每个线程使用自己的DataReader


注意,在SQL Server中有一个选项可以使用相同的连接执行多线程,称为MARS(多活动记录集)。但我不认为这是一种很好的方法来实现您的目标。

为什么不让不同的线程并行处理每个查询?我认为这不会有多大帮助。为了减少处理时间,您应该寻找代码优化和数据库查询优化。谢谢您,Neill,我们尝试运行单个查询,最后使用任务库来处理数据。但结果仍然不好:(然后,您必须查看查询本身,例如,不要使用动态查询,而是使用视图或存储过程来确保查询计划是预先确定和优化的。确保只获取所需的列。确保有适当的索引,尤其是在执行“where”和“where”时。)另一个选项是在应用程序启动时执行本地缓存。