2016-08-09 12 views
1

2番目の非同期メソッドを呼び出すために最初の非同期呼び出しで結果を使用する必要がありますが、メソッド2を終了する前にWeb APIが空の結果を返します。asp web apiで2番目の非同期呼び出しで非同期結果を待つ方法

私は.ContinueWithを使用しようと試みてきたが、それがデッドロック

に表示されますと、誰かが解決策のいくつかの種類に私をリードしてもらえますか?

例:

public class AsyncApiController : ApiController 
{ 
    [ActionName("GetClientBySSN")] 
    public async Task<IHttpActionResult> GetClientBySSN(string ssn) 
    { 
     return Ok(await _repository.GetClientBySSN(ssn)); 
    } 
} 

public interface IResRepository 
{ 
    Task<ClientResponse> GetClientBySSN(string ssn); 
} 

public class ResRepository : IResRepository 
{ 
    public Task<ClientResponse> GetClientBySSN(string ssn) 
    { 
     //async method 
     Task task1 = _service.GetClientNumberBySSN(ssn); 
     int clientNumber = task1.Result.clientnumber; 

     if (clientNumber != null) 
     { 
      //another async method that uses ID from the first result 
      return _service.GetClientDetailsByClientNumber(clientNumber); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 
+5

'int型clientNumber =(のawaitタスク1).clientnumber文脈自由な状況に落ちるように見える(偽).ConfigureAwait;'。あなたがそれを待つことができるときに 'Task.Result'を使ってタスクをブロックしないでください。 – user3185569

答えて

3

あなたのメソッドのシグネチャにasyncを追加し、あなたの方法であなたのメソッドの呼び出しでawaitキーワードを追加する必要がありました。

intインスタンスがnull(ifステートメント)の場合、コードを変更する必要がある場所と、コードが意味をなさない場所をマークしました。

public class ResRepository : IResRepository 
{ 
    // missing async 
    public async Task<ClientResponse> GetClientBySSN(string ssn) 
    { 
     // missing await - also use await and get result directly instead of getting the task and then awaiting it 
     var client = await _service.GetClientNumberBySSN(ssn); 

     // type int can never be null, this will never eval to false. maybe you meant int? above 
     // I changed to to client null check instead, maybe that is what you were going for 
     if (client != null) 
     { 
      //another async method that uses ID from the first result 
      // change - missing await 
      return await _service.GetClientDetailsByClientNumber(client.clientNumber); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 

また、のawait /非同期サフィックスAsyncとを利用して、あなたの方法に名前を付けることをお勧めします。したがってGetClientDetailsByClientNumberGetClientDetailsByClientNumberAsyncになり、GetClientBySSNGetClientBySSNAsyncになります。これにより、コードの実装の詳細が呼び出し側に明確になります。

+0

シンプルなソリューション、ありがとう – aghaux

0

ウェブアプリケーションや一般的にネットワークアプリケーションサービスの場合は、クライアント側とサーバー側を区別してください。

まず、クライアントを非同期にするために非同期APIは必要ありません。両側は完全に独立しています。だから私の最初の提案は、クライアントだけを非同期にし、Web APIをサーバ上の同期呼び出しとして維持することです(もちろん、呼び出し、ロードバランシングなどを引き起こすアプリケーションホストフレームワークが存在する可能性があります)。 )。

第2の点は、非同期APIの影響に関連しています。つまり、クライアントのインフラストラクチャに要求の完了が通知されるはずであるため、クライアント側で開く必要がある通知を受け取るチャネルがあります。このインターフェイスの設計中に完全にはっきりとわかることはありませんでした。だから、明確なアーキテクチャ要件がない限り、クライアントのためだけに非同期バージョンのインタフェースを使用します。

あなただけの古典非同期でコードを固定した場合に、最終的なノートで、バックあなたの質問に、 - 待ってすべての道...時間の

99%は、Fooのを待つべきである)はFooを(待ちます()

そして、あなたの場合は

関連する問題