C# 使用同一事务实例逐个等待所有任务失败c
我在一个事务实例中使用逐个等待方法,在对事务实例调用Commit方法时出现以下错误: 我错过了什么 代码如下:C# 使用同一事务实例逐个等待所有任务失败c,c#,transactions,task-parallel-library,dapper,C#,Transactions,Task Parallel Library,Dapper,我在一个事务实例中使用逐个等待方法,在对事务实例调用Commit方法时出现以下错误: 我错过了什么 代码如下: . . . using Dapper; using DapperExtensions; . . . using (var connection = new SqlConnection(connectionString)) { connection.Open(); var tlis = Ge
.
.
.
using Dapper;
using DapperExtensions;
.
.
.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
var tlis = GetTlis(connection).ToList();
using (var trans = connection.BeginTransaction())
{
var tasks = tlis.Take(10).Select(tli => Task.Factory.StartNew(
(dynamic @params) =>
{
ProcessTli(@params.Connection, @params.Transaction, tli);
},
new { Connection = connection, Transaction = trans }
)).ToList();
var tlisAmount = 0;
while (tasks.Count > 0)
{
//const int timeout = 3600*1000;
var winner = Task.WaitAny(tasks.ToArray());
if (winner < 0)
break;
tlisAmount++;
tasks.RemoveAt(winner);
Cmd.Write("({0}%) ", tlisAmount*100/tlis.Count);
var timeSpan = TimeSpan.FromSeconds(Convert.ToInt32(stopWatch.Elapsed.TotalSeconds));
Cmd.Write(timeSpan.ToString("c") + " ");
Cmd.Write("Processing {0} of {1} ", tlisAmount, tlis.Count);
Cmd.Write('\r');
}
try
{
trans.Commit();
}
catch (Exception e)
{
Cmd.WriteLine(e.Message);
trans.Rollback();
}
finally
{
connection.Close();
}
}
}
private static void ProcessTli(IDbConnection connection, IDbTransaction transaction, Tli tli)
{
var quotesTask = Task.Factory.StartNew(() => GetQuotesByTli(connection, transaction, tli));
quotesTask.ContinueWith(quotes =>
{
quotes.Result.ToList().ForEach(quote =>
{
var tliTransaction = new TliTransaction(quote);
connection.Insert(tliTransaction, transaction);
});
});
var billOfLadingsTask = Task.Factory.StartNew(() =>GetBillOfLadings(connection, transaction, tli));
billOfLadingsTask.ContinueWith(billOfLadings =>
{
var bolGroupsByDate = from bol in billOfLadings.Result.ToList()
group bol by bol.Year;
bolGroupsByDate.ToList().ForEach(bolGroupByDate =>
{
var bol = new BillOfLading
{
As400FormatQuoteDate = bolGroupByDate.ElementAt(0).As400FormatQuoteDate,
CommodityCode = tli.CommodityCode,
TariffOcurrenciesAmount = bolGroupByDate.Count(),
TliNumber = tli.TliNumber
};
var tliTransaction = new TliTransaction(tli, bol);
connection.Insert(tliTransaction, transaction);
});
});
Task.WaitAll(quotesTask, billOfLadingsTask);
}
提前感谢我会做一些类似于此说明的事情这显示了过程,而不是extact代码
public void ModifyData()
{
using (var connection = new SqlConnection(connectionString))
{
var tlis = GetTlis(connection).ToList();
connection.Open();
Quotes quotes;
BillOfLading billOfLading;
using (var trans = connection.BeginTransaction())
{
quotes = GetQuotesByTli(connection, transaction, tli);
billOfLading = GetBillOfLadings(connection, transaction, tli);
}
}
// Process those items retrieved from the database.
var processedItems = this.Process(/* the items that you want to process */);
using (var connection = new SqlConnection(connectionString))
{
var tlis = GetTlis(connection).ToList();
connection.Open();
using (var trans = connection.BeginTransaction())
{
// do all your inserts.
}
}
}
然后运行它:
await Task.Run(() => ModifyData());
这是一个运行多个任务的非常好的示例。我认为您应该使用Task.Run而不是Task.Factory.start如果我是您,我会尝试减少事务范围内的计算量等。我认为一个事务范围应该只读取/写入数据,而不是计算等。我不知道如何从该事务范围中取出一些代码。我只是从数据库中检索一些数据,并在表中插入新行。那么,为什么要生成所有这些任务呢。还有成吨成吨的代码?简单地将一个对象投影到另一个对象不需要产生大量任务。我必须循环遍历37900条记录,然后针对每个查询,两个不同的表获取两个记录集,然后插入到另一个表中。我不希望不相关的方法等待不必要的执行。我不确定这样做是否正确。这就是为什么我在寻找不同的观点。