Parallel.Foreach 使用 OledbDataReader 调用 Web API 会导致重复的行



我有一个包含 7 列和 10 行的数据库表。每行都为 Web API 调用提供一个输入参数,并将 API 返回的响应插入到表中。我的问题是,Parallel.Foreach没有产生与常规ForEach相同的结果。

具体来说,如果第一行的地址是"123 Jump Street Arizona Us",我从 web api 收到一个响应,标准化地址为"123 Jump Street Arizona USA",就像我有 10 个不同的行,有 10 个不同的输入地址。 但是,我从Parallel.Foreach得到的输出响应是针对重复 5 次的同一地址。下次我运行它时,结果完全不同

有人可以指出为什么会发生这种情况以及潜在的解决方案吗?

这是我的代码:

public void Main()
{
// TODO: Add your code here
string query = "SELECT  ADDR_LINE_ONE,ADDR_LINE_TWO,ADDR_LINE_THREE,COUNTRY,PROVINCE,CITY_NAME,POSTAL_CODE FROM Addresstestpoc";
try
{
using (OleDbConnection connection = new OleDbConnection(conn))
{
OleDbCommand command = new OleDbCommand(query, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
int i = reader.FieldCount;
bool b = reader.HasRows;
Parallel.ForEach(GetFromReader(reader), record =>
{                                                                      
//AddrOne = record[0].ToString();                                                            
string AddrOne = record.GetString(0);
string AddrTwo = record.GetString(1);
string AddrThree = record.GetString(2);                                                                                  
string Country = record.GetString(3);                                                          
string Province = record.GetString(4);                                                                                  
string City = record.GetString(5);                                                                                  
string PostalCode = record.GetString(6);                                                                                 
string Sender = "G";                                                                               
//sqlk = (string)Dts.Variables["User::sqlconn"].Value;                                                                               
standardizeAddressReturn result;                                                                                
string data = string.Empty;                                                                                
string queri;

MDMStandardizeAddressService web = new MDMStandardizeAddressService();
try
{                                                                                   
result = web.standardizeAddress(AddrOne, AddrTwo, AddrThree, City, Province, PostalCode, Country, Sender);
data = SerializeToXml(result);                                                                                    
queri = "insert into [CPM].[dbo].[AddressResponsetest_new] values ('" + data + "')";                                                             
//MessageBox.Show(data);                                                         
insertintosql(queri);                                                                                
}                                                    
catch (Exception ex)
{                                                                            
MessageBox.Show(ex.Message);
}
});
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
IEnumerable<IDataRecord> GetFromReader(IDataReader reader)
{
while (reader.Read()) yield return reader;
}

我认为你需要另一种方法。 命令和数据读取器不是线程安全的。 即使 DataReader 是线程安全的,它也是一个仅向前的游标,因此它不会更快。

我推荐生产者消费者模式(.e.g BlockingCollection(。在消费者中,您可以并行处理

MDMStandardizeAddressService web = new MDMStandardizeAddressService();
try
{

您可能可以使用任务,等待,异步生产者消费者。

一种更简单的方法可能是为属性创建一个类并将其放在列表中,然后只读取该列表。 这将发生在几分之一秒内。

然后,您可以并行处理列表。

存根代码:

public class WebMailer
{ 
public void process()
{
List<Addr> Addrs = new List<Addr>();
SqlCommand command = new SqlCommand();
using (var reader = command.ExecuteReader())
{
using (SqlDataReader r = command.ExecuteReader())
{
Addrs.Add(new Addr(r.GetString(0), r.GetString(1)));
}
}
foreach(Addr addr in Addrs)  // can use parallel here
{ }
}
}
s

相关内容

  • 没有找到相关文章

最新更新