C# 对循环内部数据库的异步调用

C# 对循环内部数据库的异步调用,c#,asynchronous,task-parallel-library,C#,Asynchronous,Task Parallel Library,我试图调用数据库并将结果存储在记录中,存储的进程总是返回4条记录,但有一段时间我得到了3条记录,读卡器显示4个计数,但第一条记录中为空。代码有什么问题 List record = new List(); List<Task> listOfTasks = new List<Task>(); for (int i = 0; i < 2; i++) { listOfTasks.Add(Task.Factory.StartNew(() => {

我试图调用数据库并将结果存储在记录中,存储的进程总是返回4条记录,但有一段时间我得到了3条记录,读卡器显示4个计数,但第一条记录中为空。代码有什么问题

List record = new List();

List<Task> listOfTasks = new List<Task>();

for (int i = 0; i < 2; i++)
{
    listOfTasks.Add(Task.Factory.StartNew(() => {
        IDataCommand cmd = ds.CreateCommand("DropTicket", "returnTableTypeData",
            CommandType.StoredProcedure);
        IDataReader reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            TicketTextOutputRecord rec = new TicketTextOutputRecord();
            rec.ValidationNumber = (string)reader["ValidationNumber"];
            rec.IsSuccess = (bool)reader["IsSuccess"];
            rec.Error = (string)reader["Error"];
            record.Add(rec);
        }
        //reader.Close();
        //reader.Dispose();
    }));
}

Task.WaitAll(listOfTasks.ToArray());

return record;
列表记录=新列表();
List listOfTasks=新列表();
对于(int i=0;i<2;i++)
{
添加(Task.Factory.StartNew(()=>{
IDataCommand cmd=ds.CreateCommand(“DropTicket”、“returnTableTypeData”,
CommandType.StoredProcess);
IDataReader reader=cmd.ExecuteReader();
while(reader.Read())
{
TicketTextOutputRecord rec=新的TicketTextOutputRecord();
rec.ValidationNumber=(字符串)读取器[“ValidationNumber”];
rec.issucess=(bool)读卡器[“issucess”];
记录错误=(字符串)读取器[“错误”];
记录。添加(rec);
}
//reader.Close();
//reader.Dispose();
}));
}
Task.WaitAll(listOfTasks.ToArray());
返回记录;

这听起来像是并发错误;不打算同时访问连接;允许您重叠读卡器(如果启用了MARS),但实际的访问仍然不能是并发的,因为多个线程试图同时执行任务。当你这么做的时候,所有的行为都是未定义的。坦白地说,我只是按顺序执行这些,而不是同时执行。请注意,如果使用完全不相关的连接,则允许您同时工作。

我以前修复了完全相同的错误

列表不是线程安全的

在并发添加项时,列表的内部指针可能会混淆,并且即使添加了非null值,也会导致项返回null

这就产生了问题:

var list = new List<object>();
var listOfTasks = new List<Task>();

for (var i = 0; i < 10; i++)
{
    listOfTasks.Add(Task.Factory.StartNew(() => list.Add(new object())));
}

Task.WaitAll(listOfTasks.ToArray());

为什么要循环使用硬代码值?这只是一个示例,稍后我将对其进行更改。
List
类不是线程安全的。看看这个:。我的要求是,在一个200或更多计数的循环中从UI调用服务并发送10000条记录,然后在服务中将这10000条记录分成小块,比如说100条,然后调用DB 100次,保存一个集合中100次调用的结果并发送回UI。任何建议对我都很有帮助。除了MJWLIIS建议之外,打开多个连接,然后@ A.VelMA.@ VARMA,也考虑<代码>并行。对于 >因此,您可以控制Max DOPDOS<代码>列表记录= NeXList](<代码>为您编译@weichch?需要说明的是,
listOfTasks.Add
是100%安全的<代码>记录。添加可能(也可能不)安全。我们没有足够的知识来做出判断。@mjwills OP可能共享也可能不共享可以编译的代码。我不会仅仅因为代码无法编译就认为
列表
不是
列表
。@weichch:我没有尝试你提到的并行。因为解决了我的问题。可能是真实数据,我可能需要你的解决方案。@weichch:现在我使用你提到的并行解决方案。因为在我的情况下不起作用。但问题是:我有记录列表,我必须根据app.config值批量发送记录。假设值为10,那么我必须一次向DB发送10条记录,并继续异步向DB发送10条记录,直到列表为空。我有一个表类型变量,我正在从该列表中为其创建DataTable。
var listOfTasks = new List<Task<object>>();

for (var i = 0; i < 10; i++)
{
    listOfTasks.Add(Task.Factory.StartNew(() => new object()));
}

var list = await Task.WhenAll(listOfTasks.ToArray());

// OR

Task.WaitAll(listOfTasks.ToArray());
var list = listOfTasks.Select(t => t.Result).ToList();