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