从不同的异步方法向列表中添加项目



请帮帮我。我刚刚在数据库中的3个表上创建了3个请求,我需要运行以下代码:

var totals = new List<StockTransaction>();
totals.AddRange(GetStockIn(siteCode));
totals.AddRange(GetStockOut(siteCode));
totals.AddRange(GetStockAdjustment(siteCode));
private async Task<List<StockTransaction>> GetStockIn(string site)
{
return DbContext.StockIn
.Where(y => y.StkInID.Substring(0, 4) == site)
.ToList()
.Select(y => new StockTransaction
{
ItemCode = y.prodID,
SiteCode = site,
TransactionDate = y.StkInDate.Value,
Movement = "Stock in",
// And more
})
.ToList();
}
// GetStockOut and GetStockAdjustment are exactly the same than StockIn with minor adjustments.

现在,我如何将所有这3个查询动态添加到我的股票交易列表中,并在parallen中运行它们,等待3个请求的结束,继续代码?

我想我需要使用wait,但在3个呼叫后只使用一次。也许我必须创建一个任务列表,而不是股票交易列表。我有点迷路了。

你能帮我吗?

我已经试过这个了

var totals = new List<StockTransaction>();
var task1 = GetStockIn(siteCode);
var task2 = GetStockOut(siteCode);
var task3 = GetStockAdjustment(siteCode);
await Task.WhenAll(task1, task2, task3);
totals.AddRange(task1.Result);
totals.AddRange(task2.Result);
totals.AddRange(task3.Result);

但它不起作用。我看到等待前的3行一个接一个地花时间,然后等待后的3行执行得很快。

编辑

我也试过

private async Task<List<StockIn>> GetStockIn(string site)
{
return DbContext.StockIn
.Where(y => y.StkInID.Substring(0, 4) == site)
.ToListAsync();
}

也不起作用。我不明白。

您的查询实际上需要异步才能有机会在并行中运行

private async Task<List<StockTransaction>> GetStockIn(string site)
{
return (await DbContext.StockIn
.Where(y => y.StkInID.Substring(0, 4) == site)
.ToListAsync())
.Select(y => new StockTransaction
{
ItemCode = y.prodID,
SiteCode = site,
TransactionDate = y.StkInDate.Value,
Movement = "Stock in",
// And more
})
.ToList();
}

wait将把方法分为两部分,第一部分将进行数据库调用,然后返回,在调用完成之前,第二部分只在数据库调用完成后运行,然后任务才会完成。

执行任何类型的并发查询当然都需要不同的数据库连接,即不同的dbContext对象。因此,您也许应该将查询封装在一个类中,该类创建上下文、执行查询并处理上下文。这遵循了使用短期上下文对象的思想,并依靠连接池来避免为每个上下文重新创建连接。

在等待结果时,您需要使用适当的重载,该重载接受任务的数组或列表

await Task.WhenAll( new []{task1, task2, task3});

您的内部函数应该类似于

private async Task<IReadOnlyList<StockTransaction>> GetStockIn(string site)
{
return await DbContext.StockIn
.Where(y => y.StkInID.StartsWith(site))
.Select(y => new StockTransaction
{
ItemCode = y.prodID,
SiteCode = site,
TransactionDate = y.StkInDate.Value,
Movement = "Stock in",
// And more
})
.ToListAsync();
}

注意,我们在async方法中调用返回ToListAsync()方法的不可重写Task<T>await

然后,您可以使用Task.WhenAll组合您的三个版本,以便它们可以同时运行。

var combinedStockTransactions = (await Task.WhenAll(new[]
{
GetStockIn(siteCode),
GetStockOut(siteCode),
GetStockAdjustment(siteCode)
})
.SelectMany(st => st)
.ToList();

最新更新