2016-04-12 22 views
0

私は非同期Web APIプログラミングに関する非常に基本的な疑問があります。私はSaveCaseSearchを私のコントローラに非同期で呼びたいと思っています。しかし、コールはDALのさまざまなレイヤーを通過し、最終的にDBを呼び出します。Web Apiの非同期コントローラ

これらの連続コールも非同期にする必要がありますか?

私は非常に非同期的な世界に新しいので、私はすでにいくつかの間違いを犯している可能性があります。何かが間違っているようであれば私を修正してください

は今、非同期モードで呼び出す必要がある

/*Create API for Case*/ 
[HttpPost] 
[Route("createcase")] 
public IHttpActionResult PostCreateCase([FromBody] ARC.Donor.Business.Case.CreateCaseInput CreateCaseInput) 
{ 
    ARC.Donor.Service.Case.CaseServices cs = new ARC.Donor.Service.Case.CaseServices(); 
    var searchResults = cs.createCase(CreateCaseInput); 
    List<CreateCaseOutput> searchOutputResults = (List<CreateCaseOutput>)searchResults; 
    if (!string.IsNullOrEmpty(searchOutputResults.ElementAt(0).o_case_seq.ToString())) 
     SaveCaseSearchDetails(SaveSearchInput); /*This should be called asynchronously*/ 
    return Ok(searchResults); 
} 

この

SaveCaseSearchDetails:

ので、コントローラのため、私は以下のような何かをやっています。だから私は書かれています:

[HttpPost] 
public async Task<IHttpActionResult> SaveCaseSearchDetails([FromBody] ARC.Donor.Business.SaveSearchInput SaveSearchInput) 
{ 
    ARC.Donor.Service.Case.CaseServices cs = new ARC.Donor.Service.Case.CaseServices(); 
    var searchResults = await cs.saveCaseSearchDetails(SaveSearchInput); 
} 

をそれが正しい

されている場合は、連続した呼び出しがあまりにも非同期すべきか?

今、彼らは

public IList<Entities.Case.SaveCaseSearchOutput> saveCaseSearch(ARC.Donor.Data.Entities.Case.SaveCaseSearchInput SaveCaseSearchInput) 
{ 
    Repository rep = new Repository(); 
    string strSPQuery = string.Empty; 
    List<object> listParam = new List<object>(); 
    SQL.CaseSQL.getCreateCaseParameters(SaveCaseSearchInput, out strSPQuery, out listParam); 
    var AcctLst = rep.ExecuteStoredProcedure<Entities.Case.SaveCaseSearchOutput>(strSPQuery, listParam).ToList(); 
    return AcctLst; 
} 

あるために

SQL.CaseSQL.getCreateCaseParameters

方法は、非同期的に呼び出される必要がありますか? しかし、その場合はすぐに次の行

rep.ExecuteStoredProcedure

が正常に右に実行することはできませんか? strSPQueryは前の行自体から来ているので?

私は間違った方法で考えていますか?私を修正してください。

+1

'これらの連続した呼び出しも非同期にするべきですか? ' 「真の」非同期機能が必要な場合はあります。 –

+0

しかし、その場合、私が描いた最後のケースのように、それは正しく機能しませんか? – StrugglingCoder

+0

「非同期」は何を期待していますか?ブロッキング操作が*非同期でない限り、スレッドをブロックして実行する必要があります。 –

答えて

1

それは非同期metodsには使用できませんoutキーワードを使用していますので、あなたは(のawaitで)非同期的にSQL.CaseSQL.getCreateCaseParametersを呼び出すことはできません。

DBコールを非同期にするには、awaitというDBメソッドを見つける必要があります。次に、saveCaseSearchメソッドをasyncに変更して、コントローラメソッドから待機させることができます。

+0

今のところ、私は既存のサービスとDALレイヤーの機能を破りたくありません。私はそれらを同期させておくことができますか?または、それは非同期トポロジに対してですか?アプリケーションでパフォーマンスの問題が発生しますか? – StrugglingCoder

+0

非同期メソッドに 'await'がない場合、非同期メソッドは同期して実行されるため、予期しないことは起こりません。あなたのIDEはあなたに警告するかもしれませんが、それについてのことです。 (コントローラのメソッドasyncを無意味にすることは無意味ですが、同期させることもできます) – GWigWam

+2

@StrugglingCoder非同期を使用する場合は、同期DALを破棄して*非同期*メソッドを追加して、 *実際の*非同期データベース呼び出し。たとえば、ExecuteReaderではなくExecuteReaderAsyncを呼び出します。そうしないと、元のスレッドかTask.Runで始まるスレッドのいずれかをブロックすることになります。あなたは何も得られませんが、余分なオーバーヘッドを支払うでしょう。 –

5

これらの連続コールも非同期にする必要がありますか?

はい。

SaveCaseSearchDetails

は現在、非同期モードにそれを行うための苦労してい

に呼び出す必要があります。

より自然なアプローチは、以外のエンドで開始することです。実際にデータベースクエリを実行しているコードの部分は、いずれも非同期である必要があります最初にです。その後、awaitを使用して呼び出すと、というメソッドが作成されます。最後にの最後のというコントローラアクションに到達するまで、awaitなどで呼び出す必要があります。 PostCaseCreate方法で

実際に私が直面しています問題があるSaveCaseSearchDetails(SaveSearchInputが)多少、我々はリターンOK(にsearchResults)のため

ああを待ちたくないので、非同期に呼び出す必要があり、それはですまったく異なる質問。あなたはに戻りたいと思います。Asyncはこれを行うのに役立ちません。私のブログ(とMSDN article on async ASP.NET)で説明しているように、async does not change the HTTP protocol

returning early or "fire and forget" on ASP.NETにはいくつかの方法があり、私のブログで説明しています。ただし、ASP.NET は、このシナリオではのために設計されていないため、注意深く踏む必要があります。完全に信頼できる唯一のソリューションは、適切に分散されたアーキテクチャです。

+0

洞察に感謝します。しかし、SQL.CaseSQL.getCreateCaseParameters(SaveCaseSearchInput、out strSPQuery、out listParam); var AcctLst = rep.ExecuteStoredProcedure (strSPQuery、listParam).ToList(); 最初の行にはoutキーワードが含まれていますが、これは私が想定しているものではサポートされていません。また、直前の行では、outキーワードの結果が使用されます。 async/awaitアプローチを使用してそれを達成する方法は? – StrugglingCoder

+1

@StrugglingCoder:あなたはまだ間違った方向からこれに近づいています。 'getCreateCaseParameters'がdb(おそらくそうです)と話していない場合は、それを' async'にする必要はありません。そうであれば、2つの値を返すだけです。 –

関連する問題