C# 使用同一事务实例逐个等待所有任务失败c

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

我在一个事务实例中使用逐个等待方法,在对事务实例调用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);
        }

提前感谢

我会做一些类似于此说明的事情这显示了过程,而不是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条记录,然后针对每个查询,两个不同的表获取两个记录集,然后插入到另一个表中。我不希望不相关的方法等待不必要的执行。我不确定这样做是否正确。这就是为什么我在寻找不同的观点。