2017-06-12 4 views
1

MDNチュートリアルのような.NET Async/Awaitの例には厳しい時間があります。.NET WebApi非同期コントローラのアクションが永遠に実行

私はコントローラのアクション非同期を作るために、集まったものから、私がしなければならない:

  1. は、メソッド名の前にasyncを追加します。
  2. awaitを追加すると、プライマリタスクが実行されます。
  3. ストアまたはリポジトリから取得する場合は、Task.Run()をStoreメソッドに追加する必要があります。私は、コンパイラでエラーや警告がなく、この方法だけでハングアップ、それを行うとき
  4. async方法はTask<>

を返す必要があります。どこが間違っていますか?

PostsController.cs

public async Task<IHttpActionResult> Get() 
    { 
     PostsStore store = new PostsStore(); 
     List<Post> AsyncResult = await store.GetPosts(); 
     return Ok(AsyncResult); 
    } 

PostsStore.cs

public async Task<List<Post>> GetPosts() 
    { 
     List<Post> result = await Task.Run(() => { 
      List<Post> posts = new List<Post>(); 
      string conn = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; 
      using (SqlConnection connection = new SqlConnection(conn)) 
      { 
       SqlCommand command = new SqlCommand(); 
       command.Connection = connection; 
       command.CommandText = "GetPosts"; 
       command.CommandType = System.Data.CommandType.StoredProcedure; 

       connection.Open(); 
       SqlDataReader dr = command.ExecuteReader(); 
       while (dr.Read()) 
       { 
        Post post = new Post() 
        { 
         PostId = (int)(dr["PostId"]), 
         Title = dr.SafeGetString("Title"), 
         Body = dr.SafeGetString("Body"), 
         SaveTitle = dr.SafeGetString("SaveTitle"), 
         SaveBody = dr.SafeGetString("SaveBody"), 
         Slug = dr.SafeGetString("Slug"), 
         State = dr.SafeGetString("State"), 
         IsPublished = (bool)(dr["IsPublished"]), 
         LastSaved = (DateTime)(dr["LastSaved"]), 
         CreateDate = (DateTime)(dr["CreateDate"]) 
        }; 
        posts.Add(post); 
       } 
       dr.Close(); 
       connection.Close(); 
       return posts; 
      } 

     }); 

     return result; 

    } 
+1

Task.Runの必要はありません。また、usingステートメントでラップされているときに閉じる必要はありません。 – mason

答えて

1

ここTask.Runの必要はありません。使用可能な非同期呼び出しを使用するようにメソッドをリファクタリングすることを検討できます。

public class PostsStore { 
    public async Task<List<Post>> GetPostsAsync() { 
     var posts = new List<Post>(); 
     var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; 
     using (var connection = new SqlConnection(connectionString)) { 
      var command = new SqlCommand(); 
      command.Connection = connection; 
      command.CommandText = "GetPosts"; 
      command.CommandType = System.Data.CommandType.StoredProcedure; 

      await connection.OpenAsync(); 
      using (var reader = await command.ExecuteReaderAsync()) { 
       while (await reader.ReadAsync()) { 
        var post = new Post() { 
         PostId = (int)(reader["PostId"]), 
         Title = reader.SafeGetString("Title"), 
         Body = reader.SafeGetString("Body"), 
         SaveTitle = reader.SafeGetString("SaveTitle"), 
         SaveBody = reader.SafeGetString("SaveBody"), 
         Slug = reader.SafeGetString("Slug"), 
         State = reader.SafeGetString("State"), 
         IsPublished = (bool)(reader["IsPublished"]), 
         LastSaved = (DateTime)(reader["LastSaved"]), 
         CreateDate = (DateTime)(reader["CreateDate"]) 
        }; 
        posts.Add(post); 
       } 
      } 
     } 
     return posts; 
    } 
} 

非同期メソッド

public async Task<IHttpActionResult> Get() { 
    var store = new PostsStore(); 
    var posts = await store.GetPostsAsync(); 
    return Ok(posts); 
} 

と命名規則を反映するために、メソッド名のメモ更新今すぐそれと邪魔にならないように、多くの懸念がで起こっているのが方法として上記のクラスをリファクタリング/見直しを検討将来的には問題を維持することができます。

+0

ありがとう!私はこれを試してみましょう。高いレベルでは、他に何をリファクタリングしますか?読者が値を投稿にどのように割り当てるか? –

関連する問題