MVC 6 비동기 액션

asp.net-mvc asynchronous c# dapper

문제

그래서 저는 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);
}

하지만 그때 나는 깨달았 / 그것을 비동기 수 있도록 기억, 나는 TaskTask 필요 같은 :

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

하지만 이미 내 repos에서 "기다리고"하고 있습니다.

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

이것은 양쪽 모두 repo 호출을 비동기 적으로 (병렬로) 수행합니까?

수락 된 답변

컨트롤러에서도 기다려야합니다. 엄지의 규칙 : 절대로 말하지 마라. .Result , 대신에 await .

또한 액션 메서드를 public async 로 선언해야합니다.

업데이트 : 비동기식으로 리포지토리를 호출하는 올바른 방법 일 것입니다. 데이터베이스 호출은 두 가지 태스크가 기다리기 전에 시작되므로 모두 병렬로 수행되어야합니다. DB 메소드의 시작과 끝 부분에 디버그 로깅을두고 "start 1 end 1 start 2 end 2"대신 "start 1 start 2 end 1 end 2"또는 비슷한 것을 볼 수 있습니다. 귀하의 질의는 상당히 느립니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow