所以我开始了将我的 nHibernate 网站转换为使用 Dapper 的概念验证。
我正在使用的操作方法现在似乎正在运行:
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
var invoice = invoiceRepo.GetInvoiceAsync(19992031);
var allInvoices = invoiceRepo.GetAllInvoicesAsync();
var model = new Models.AboutModel
{
Invoice = invoice.Result,
AllInvoices = allInvoices.Result
};
return View(model);
}
但后来我意识到/记得,为了使其异步,我需要 Task
在 Action 上,像这样:
public Task<IActionResult> About()
{
ViewData["Message"] = "Your application description page.";
var invoice = invoiceRepo.GetInvoiceAsync(19992031);
var allInvoices = invoiceRepo.GetAllInvoicesAsync();
var model = new Models.AboutModel
{
Invoice = invoice.Result,
AllInvoices = allInvoices.Result
};
return View(model);
}
但是一旦我这样做,它就会告诉我需要等待一些事情。在我见过的所有示例中,它只是显示如下内容:
var result = await repo.Get(param);
但我已经在我的存储库中进行“等待”了。
public async Task<Invoice> GetInvoiceAsync(int invoiceId)
{
const string query = "select InvoiceId, Name [InvoiceName] from dbo.Invoice where InvoiceId = @invoiceId";
using (var conn = GetConnection())
{
var dp = new DynamicParameters();
dp.Add("@invoiceId", invoiceId);
await conn.OpenAsync();
var invoiceResult = await conn.QueryAsync<Invoice>(query, dp, null, 30, CommandType.Text);
var invoice = invoiceResult.SingleOrDefault();
return invoice;
}
}
public async Task<List<Invoice>> GetAllInvoicesAsync()
{
const string query = "select InvoiceId, Name [InvoiceName] from dbo.Invoice where SalesPeriodId >= 17";
using (var conn = GetConnection())
{
await conn.OpenAsync();
var invoiceResult = await conn.QueryAsync<Invoice>(query, null, null, 30, CommandType.Text);
var invoices = invoiceResult.Take(1000).ToList();
return invoices;
}
}
所以我切换到异步的全部意义在于能够异步执行我的两个调用,然后在返回时将结果合并在一起。
如何更改我的 Controller 操作以异步执行此操作,同时拥有 Task<IActionResult>
?像这样:
public Task<IActionResult>About() {}
更新:那么这是正确的吗?
public async Task<IActionResult> About()
{
ViewData["Message"] = "Your application description page.";
var invoice = invoiceRepo.GetInvoiceAsync(19992031);
var allInvoices = invoiceRepo.GetAllInvoicesAsync();
var model = new Models.AboutModel
{
Invoice = await invoice,
AllInvoices = await allInvoices
};
return View(model);
}
这会异步(并行)执行两个 repo 调用吗?
最佳答案
你也需要在你的 Controller 中等待。经验法则:永远不要说 .Result
,而是说 await
。
您还应该将您的操作方法声明为 public async
。
更新:那将是异步调用存储库的正确方法。数据库调用应该并行发生,因为两个任务都在等待任何事情之前开始。您总是可以自己看到这一点,方法是将调试日志记录放在数据库方法的开头和结尾,并看到您得到“start 1 start 2 end 1 end 2”或类似的东西而不是“start 1 end 1 start 2 end 2”如果您的查询相当慢。
关于c# - MVC 6 异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35612294/