返回 Task<object> 而不是 List 时对象不可等待

Object not awaitable when returning Task<object> instead of List

我有这个方法应该 return 只有一个项目对象。 IntelliSense 告诉我将其更新为 return a Task 但随后我必须更改 属性 的声明(我想确认只有一个项目正在 returned ,因此 .Result.First() 但是我收到一条错误消息,指出项目不可等待。

 public async Task<Project> GetProjectDataAsync(int projectId)
        {
            return await _db.LoadData<Project, dynamic>("dbo.Sp_Get_Project_Data_By_ProjectId",
                new { projectId },
                ConnectionStringName,
                true).Result.First();
        }

这是电话:

 public Project Project { get; set; }
 public async Task OnGetAsync(int projectId)
        {
            Project = await _db.GetProjectDataAsync(projectId);

        }

如果值得注意,我正在使用 Dapper 连接到具有以下 LoadData 定义的数据库:

 public async Task<List<T>> LoadData<T, U>(string sqlStatement, U parameters, string connectionStringName, bool isStoredProcedure = false)
        {
            string connectionString = _config.GetConnectionString(connectionStringName)!;

            CommandType commandType = CommandType.Text;

            if (isStoredProcedure == true)
            {
                commandType = CommandType.StoredProcedure;
            }

            using (IDbConnection connection = new SqlConnection(connectionString))
            {
                var rows = await connection.QueryAsync<T>(sqlStatement, parameters, commandType: commandType);
                return rows.ToList();
            }
        }

await先得到LoadData的结果再得到列表的第一个元素:

public async Task<Project> GetProjectDataAsync(int projectId)
{
    var result = await _db.LoadData<Project, dynamic>("dbo.Sp_Get_Project_Data_By_ProjectId",
                new { projectId },
                ConnectionStringName,
                true);
     return result.First();
}

或者通过在括号中等待 LoadData 调用:

public async Task<Project> GetProjectDataAsync(int projectId)
{
    return (await _db.LoadData<Project, dynamic>("dbo.Sp_Get_Project_Data_By_ProjectId",
                new { projectId },
                ConnectionStringName,
                true)).First();
}

Task<TResult>.Result 应避免在异步代码中使用(除非您确定任务已经完成):

The result value of this Task<TResult>, which is of the same type as the task's type parameter.

Accessing the property's get accessor blocks the calling thread until the asynchronous operation is complete; it is equivalent to calling the Wait method.

去掉 .Result 调用。它本质上是试图使异步操作同步。 (然后.First()确实是等不及了。)

等待的操作是_db.LoadData<Project, dynamic>(...),例如:

var data = await _db.LoadData<Project, dynamic>(
  "dbo.Sp_Get_Project_Data_By_ProjectId",
  new { projectId },
  ConnectionStringName,
  true
);
return data.First();

或者,如果您想在一行中完成,仍然 await 调用 LoadData 并将该操作括在括号中:

return (await _db.LoadData<Project, dynamic>(
  "dbo.Sp_Get_Project_Data_By_ProjectId",
  new { projectId },
  ConnectionStringName,
  true
)).First();