MVC 6 异步操作

本文关键字:异步操作 MVC | 更新日期: 2023-09-27 18:36:01

所以我已经开始了将我的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,如下所示:

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

因此,我切换到异步的全部意义在于能够异步执行我的两个调用,然后在返回时将结果合并在一起。

如何在具有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);
}

这会异步(并行)执行两个存储库调用吗?

MVC 6 异步操作

您还需要在控制器中等待。经验法则:永远不要说.Result,而是说await

您还应该将操作方法声明为 public async

更新:这将是异步调用存储库的正确方法。数据库调用应并行进行,因为这两个任务都是在等待任何内容之前启动的。如果您查询速度相当慢,您始终可以通过将调试日志记录放在数据库方法的开头和结尾并看到您得到"开始 1 开始 2 结束 1 结束 2"或类似的东西而不是"开始 1 结束 1 开始 2 结束 2"来自己看到这一点。