.NET WebApi异步控制器操作永远执行

时间:2017-06-12 01:45:51

标签: c# asp.net asynchronous asp.net-web-api

我很难关注.NET Async / Await示例,例如官方的MDN教程。

从我收集的内容来看,要使控制器操作异步,我必须:

  1. 在方法名称前添加async
  2. 在主要任务运行之前添加await
  3. 如果我从商店或存储库中提取,则必须将Task.Run()添加到商店方法。
  4. async方法必须返回Task<>
  5. 当我这样做时,编译器中没有错误或警告,该方法就会挂起。我哪里错了?

    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 个答案:

答案 0 :(得分: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);
}

现在开始考虑审查/重构上述课程,因为在那里可能会出现许多问题,这可能会使其在将来出现问题。