C# 我的任务列表只运行了两次,而它应该运行很多次

C# 我的任务列表只运行了两次,而它应该运行很多次,c#,asynchronous,C#,Asynchronous,我想在所有行上运行一个函数,但不是一次为每一行运行,而是希望它并行运行。问题是它似乎只运行了两次(而列表上有217种产品),而且行似乎是随机选择的。我不知道为什么会发生这种情况——同步版本按预期工作 该函数对使用WPF SfDataGrid中的行数据的SOAP服务进行API调用。可能API在这么多请求后关闭了连接?这真的很难说,我不知道除了写一张票和等一个星期,我还能怎么检查 从中调用函数的事件的一部分: var tasks = new List<Task>(); using (va

我想在所有行上运行一个函数,但不是一次为每一行运行,而是希望它并行运行。问题是它似乎只运行了两次(而列表上有217种产品),而且行似乎是随机选择的。我不知道为什么会发生这种情况——同步版本按预期工作

该函数对使用WPF SfDataGrid中的行数据的SOAP服务进行API调用。可能API在这么多请求后关闭了连接?这真的很难说,我不知道除了写一张票和等一个星期,我还能怎么检查

从中调用函数的事件的一部分:

var tasks = new List<Task>();
using (var db = new SqliteConnection("Data Source=file:products.sqlite"))
{
    using (var client = new ApiOrdersPortTypeClient(binding, address))
    {
        db.Open();
        // run ScanProduct() on each row in a WPF SfDataGrid
        foreach (var row in ProductList.View.Records)
        {
            tasks.Add(Task.Factory.StartNew(
                () => ScanProduct(row, desiredDays, deliveryTime, client, db)));
        }

        Task.WaitAll(tasks.ToArray());
    }
}
你的问题在这里:

tasks.Add(Task.Factory.StartNew(() => ScanProduct(row, desiredDays, deliveryTime, client, db)));
ScanProduct
是一个异步函数,因此需要等待

每次调用
Task.Factory.StartNew
都会返回一个
任务
,将使用
Task.WaitAll
等待该任务。但是,在每个任务中,调用
ScanProduct
将返回另一个任务,而
任务.WaitAll
不会等待该任务

解决方案是将异步lambda与
任务结合使用。运行
,然后在每种情况下,外部
任务
都不会完成,直到
ScanProduct
也完成

tasks.Add(Task.Run(async () => await ScanProduct(row, desiredDays, deliveryTime, client, db)));

这似乎是一个解决方案,但我需要对它进行更多的测试以确定-现在我需要重新构造一点
ScanProduct
。您的解决方案没有完全起作用,但将
Task.Factory.StartNew
替换为
Task.Run
确实达到了我的预期效果。您使用
async()=>wait-ScanProduct
的解决方案与简单的
ScanProduct
没有什么不同。在这两种情况下,
Task.Factory.StartNew
都由一个异步委托提供,这是不理解的。您应该返回
任务
,或者使用
任务。运行
方法自动展开(因为它理解异步委托)。@TheodorZoulias这很有趣,谢谢。Johnathan建议的方法确实如我预期的那样起作用,其中一个罪魁祸首是在
Task.WaitAll()期间UI挂起。查询速度快得多,但UI现在挂起。现在对我来说是公平的,但我希望有一个不同的解决方案。@xtl能够保持UI响应的异步使用<代码>等待任务。当所有(…)
而不是
任务时。WaitAll(…)
@TheodorZoulias没有意识到关于
StartNew
,我总是使用
Task.Run
。我将更新答案。您的
ScanProduct
方法不仅发出SOAP请求,而且还更新您的Sqlite数据库。你确定你的数据库是真的吗?@TheodorZoulias老实说,我没有想到这一点,因为我从来没有遇到过任何问题,在我看来,查询总是在连接关闭后进行的。这种工作的正确工具是。出于这样或那样的原因,任何其他解决方案都是次优的。例如,如果第一个产品的SOAP调用失败,您真的想等待其余216个SOAP调用也失败,然后再收到错误通知吗?因为如果使用简单易行的方法
Task.WaitAll(tasks)
wait Task.WhenAll(tasks)
,就会发生这种情况。
tasks.Add(Task.Run(async () => await ScanProduct(row, desiredDays, deliveryTime, client, db)));