1

我正在研究一個asp.net mvc5 web應用程序+實體框架6.我想在我的應用程序中有一個存儲庫模型類。目前我正在採用這種方法來實現異步操作方法和異步存儲庫模型類。在我的asp.net mvc5 web應用程序中寫入異步庫方法

例如我有以下庫保存方法: -

public class Repository 
    { 

     private Entities t = newEntities(); 

     public async Task Save() 
     { 
      await t.SaveChangesAsync(); 
     } 

這我從我的操作方法如下呼籲: -

Repository repository = new Repository(); 
public async Task<ActionResult> GetResourceByName(string resourcename) 
     { 
     await repository.Save(); 
     } 

所以這是一個正確的做法?因爲我做了以下內容: -

  1. 我定義庫方法作爲任務&也操作方法任務。所以我應該把它們都作爲Task(s)。?

  2. 我在動作方法(調用repo方法時)和存儲庫上使用了兩次await?那麼這些await是多餘的?

//請注意,這只是它只是用來保存模型庫方法的簡單的預報,但我問的是方法本身,因爲我將使用更復雜的這種方法儲存庫的方法..

回答

2
  1. Q1:是的,都應該返回任務,這就是它應該如何,它是完全沒問題的。第二季度:是的,兩者都應該有等待(如果你有更多的層次,那麼所有這些層次的所有函數調用都應該等待)。

基本上是:一旦你去異步/的await,所有的調用鏈應該是異步/ AWAIT避免線程相關的問題......

如果你不那麼等待那個叫:「火與忘記「這是不推薦的,因爲然後這個請求會以成功消息的形式返回給用戶,但是在以後的時間裏,你在沒有等待的情況下所做的調用可能會失敗並拋出一個異常,並且你不知道什麼是該異常......

+0

我完全意識到「火與遺忘」。但我仍然沒有明白爲什麼我需要在我的行動方法中等待。例如,如果我用這個「await repository.Save()」替換爲「repository.Save()// no await」,那麼通過defualt asp.net mvc將不會繼續執行,除非得到結果。因爲repo方法使用await「await t.SaveChangesAsync();」那麼它應該等到保存完成後,這是否正確?換句話說,動作方法將不會繼續執行,除非「await t.SaveChangesAsync();」是完整的,所以爲什麼我需要等待和已經等待的方法! –

+0

這不是真的。如果你不等待它不會等待,你不會知道呼叫的結果... – Aram

0

回答您的問題:

  1. 是的,他們都應該返回任務。
  2. 是的,await是有意義的。不,他們不是多餘的。

要明白你爲什麼威力(非必要)需要await兩次,我建議你看看這篇文章,其給出瞭如何和一個漂亮的明顯的例子,爲什麼它的工作原理:

C# async and await: Why Do We Need Them?

如果您想使用存儲庫和可能要考慮使用的服務爲您的業務邏輯,我建議你檢查這個項目,很容易擴展和通用:

URF - Unit of Work & Repositories Framework

在考慮從頭開始開發所有東西之前,應該先檢查一下。我真的很喜歡這個項目!

+0

感謝您提到的答覆,我需要使用兩次;在動作方法和存儲庫上。但我不知道爲什麼我需要等待已經等待的方法..因爲我正在等待repository類的entities.savechnagesasync(),所以爲什麼在調用已經等待的方法時需要使用await呢? –

+0

我編輯了我的答案,在'await'上添加更多信息。 – Maxime

2

與兩個答案相反,兩個awaits不是必需的。 awaitasync只有在繼續之前需要Task的結果時才需要。如果你不需要那個結果,那麼你不需要標記你的方法async

這意味着這種方法...

public async Task Save() 
{ 
    await t.SaveChangesAsync(); 
} 

可以簡化爲

public Task Save() 
{ 
    return t.SaveChangesAsync(); 
} 

即使這些功能都是一樣的,我喜歡的第二個版本,因爲它表明承認Task是異步工作和異步/等待只是編譯器等待完成該工作的信號。

+0

請注意,如果內部出現異常,堆棧跟蹤't.SaveChangesAsync()'不會顯示'Save()',而如果使用'await',它將會顯示。 –

+0

@Shoe謝謝你的回覆,你提到「如果你不需要那個結果,那麼你不需要將你的方法標記爲異步。」但我認爲你的意思是「如果你不需要這個結果,那麼你不需要標記你的方法正在等待」??這是正確的,因爲等待會導致系統在繼續之前等待代碼完成。 –

+0

@Shoe「與兩個答案相反,兩個等待都沒有必要。」答案並不是說他們是「必要的」,他們說這不是多餘的。這是一個主要區別。 – Maxime

1

無論其他答案,這裏是爲什麼你應該使用await和更多。

ASP.NET有一個同步上下文,它將在每個await上捕獲,並且會爲該上下文發佈延續(async方法的其餘部分)。這意味着不僅僅是線程切換,而是要用ASP.NET上下文切換到線程。

如果你的後綴異步調用(那些await一起ConfigureAwait(false)調用ASP.NET的上下文切換不會發生(儘管線程切換會)。

由於動作視圖引擎最有可能需要的ASP.NET背景下,你不能在MVC操作方法使用ConfigureAwait(false)但你要對所有被它調用的方法使用

所以,你的代碼應該是這樣的:。

public class Repository 
{ 
    private Entities t = new Entities(); 
    public async Task SaveAsync() 
    { 
     await t.SaveChangesAsync().ConfigureAwait(false); 
    } 
} 


Repository repository = new Repository(); 
public async Task<ActionResult> GetResourceByName(string resourcename) 
{ 
    await repository.SaveAsync(); 
} 

因爲在調用ConfigureAwait(false)之後await之後可能沒有ASP.NET上下文,所以您應該從ASP.NET上下文中傳遞所需的所有參數。

+0

感謝您的答覆..但我沒有得到你的觀點,爲什麼我需要添加「ConfigureAwait(false);」 SaveAsync內?在我的情況下,我不使用它,我沒有發現任何問題,所以如果我不使用它,這會導致什麼? –

+0

請閱讀[這些文章](https://docs.com/paulo-morgado/8860/async-await-general)以瞭解'async-await'是如何工作的。 –

+0

所以你的意思是我需要使用「ConfigureAwait(false);」 ?? –

相關問題