我在一个事务实例中使用所有逐个方法的等待,并且在事务实例上调用Commit方法时出现此错误:
我在这里错过了什么?
这是代码:
.
.
.
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);
}
提前致谢
答案 0 :(得分:1)
我会做这样的事情(注意这显示了过程,而不是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());
这个resource显示了运行多个任务的一个很好的例子。