簡體   English   中英

使用 async-await 進行數據庫查詢

[英]Using async-await for database queries

我目前正在開發一個 ASP NET web api 項目,該項目以異步方式對數據庫進行所有調用。

我們正在使用ServiceStack.OrmLite ,它為我們提供了一個異步和同步的 API 來進行數據庫調用。

我們這樣做的例子:

選項1

var activity = await context.SingleByIdAsync<Activity>(x => x.Id == myId);
var place = await context.SingleByIdAsync<Place>(x => x.Id == myId);

但我們也可以這樣實現。

選項 2

var activity = context.SingleById<Activity>(x => x.Id == myId);
var place = context.SingleById<Place>(x => x.Id == myId);

根據我對異步編程的了解,使用選項 1 我們阻塞線程並在操作完成時釋放它。

我認為選項 1 比選項 2 更昂貴。

Go 進入阻塞等待 - Thread.Sleep、Task.Wait 等。這意味着您在線程 A 上觸發數據庫請求,然后在該線程上輸入等待:線程已分配但被阻塞且不能用於其他任何事情。 當您的數據准備就緒時,您會以某種方式了解到這一點並退出等待,您的代碼會繼續在線程 A 上運行。

  1. 最好的方法是什么?

  2. 對數據庫調用使用異步操作有什么好處?

  3. 我們是否正確地實現了異步調用?

  4. 如果我將對數據庫的所有調用切換為同步,我會遇到問題嗎?

  1. 最好的方法是什么?

    這么少的代碼很難說出來,但一般來說,如果您願意更改調用堆棧中的所有方法並且有適當的異步方法可用,請使用它。

    所說的更改調用堆棧中的所有方法的意思是,如果您將方法TA()更改為異步(即async Task<T> AAsync()那么您還必須將任何調用A的方法也更改為異步.

    我所說的正確異步方法是什么意思:在 ASP.Net 的情況下,沒有 UI 線程,因此同步方法會阻塞哪個線程並不重要。 因此,在這種情況下,適當的異步方法將是執行一些異步 IO 並且不阻塞任何線程(甚至不是某些線程池線程)的方法。

  2. 對數據庫調用使用異步操作有什么好處?

    一般來說,在 ASP.Net 中使用異步的好處是,當請求異步等待某個(正確的)異步操作完成時,它不會阻止任何線程處理另一個請求。

    因此,只要您使用的打包程序將數據庫調用實現為適當的異步 IO,您將受益於您的服務器具有更好的可擴展性(即它可以並行處理更多請求)。

  3. 我們是否正確地實現了異步調用?

    很難從這么少的代碼中分辨出來,但只要您不在調用堆棧中使用Task.Wait() ,您可能會使用它來糾正。

  4. 如果我將對數據庫的所有調用切換為同步,我會遇到問題嗎?

    如 2. 中所述,當同時完成兩個多個請求時,您可能會遇到問題。

你說“從我對異步編程的了解來看,使用選項 1 我們正在阻塞線程並在操作完成時釋放它。” , 則相反。 當一個線程進入await時,它將異步等待等待的任務完成。 這意味着線程將可以自由地做其他事情。 完成或失敗(有例外)的任務將被安排繼續。 這取決於捕獲的同步上下文

您還說“我認為選項 1 在我們實施它的方式上比選項 2 更昂貴。” ,這並沒有完全錯誤,因為異步方法內置在 state 機器中,並且會有一點開銷。 但是由於您處於 ASP.Net 上下文中,因此使用異步操作釋放線程以處理其他請求將大大受益。

是一篇關於在 ASP.Net 上使用異步的文章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM