简体   繁体   English

等待所有具有相同事务实例的任务一一失败c#

[英]Wait all tasks one by one with the same transaction instance failed c#

I am using the wait all one by one approach inside one transaction instance and I get this error when calling the Commit method on the transaction instance:我在一个事务实例中使用了一种一种的等待方法,在事务实例上调用 Commit 方法时出现此错误:

在此处输入图片说明

What Am I missing here?我在这里缺少什么?

This is the code:这是代码:

.
.
.
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);
        }

Thanks in advance提前致谢

I would do something like this (note this shows the process, not the extact code...)我会做这样的事情(注意这显示了过程,而不是确切的代码......)

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.
        }
    }
}

Then you would run it:然后你会运行它:

await Task.Run(() => ModifyData());

This resource shows a really good example of running multiple tasks.资源显示了运行多个任务的一个非常好的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM