C# ASP MVC核心3x异步数据库调用-我没有得到什么?
我希望有人能给我带来光明,因为在VS中我在一个异常和另一个异常之间跳跃,我真的受够了。我读过关于如何执行异步调用的文章,也看过一些代码示例,但由于某种原因,我并没有根据VS得到它 我有一个简单的POCO,GetCompanyResponse,它将包含一组公司或错误,具体取决于发生的情况:C# ASP MVC核心3x异步数据库调用-我没有得到什么?,c#,sql-server,asp.net-mvc,asp.net-core,async-await,C#,Sql Server,Asp.net Mvc,Asp.net Core,Async Await,我希望有人能给我带来光明,因为在VS中我在一个异常和另一个异常之间跳跃,我真的受够了。我读过关于如何执行异步调用的文章,也看过一些代码示例,但由于某种原因,我并没有根据VS得到它 我有一个简单的POCO,GetCompanyResponse,它将包含一组公司或错误,具体取决于发生的情况: public class GetCompanyResponse { public List<Company> Companies { get; set; } public List&
public class GetCompanyResponse
{
public List<Company> Companies { get; set; }
public List<ErrorResult> Errors { get; set; }
public GetCompanyResponse()
{
Companies = new List<Company>();
Errors = new List<ErrorResult>();
}
}
公共类GetCompanyResponse
{
上市公司{get;set;}
公共列表错误{get;set;}
public GetCompanyResponse()
{
公司=新列表();
错误=新列表();
}
}
我所要做的就是将从数据库加载公司的同步调用转换为异步调用,以便在加载数据的同时释放UI
以下是我转换的方法:
public async Task<GetCompanyResponse> GetCompaniesByQuery()
{
var response = new GetCompanyResponse();
try
{
using (var conn = new SqlConnection(_configuration["Settings:DBConn"]))
{
var cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT TOP (1000) company_id, company_name, postcode FROM dbo.tbl_companies";
conn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
response.Companies.Add(new Company
{
CompanyId = Convert.ToInt32(reader["company_id"]),
CompanyName = reader["company_name"].ToString(),
PostCode = reader["postcode"].ToString()
});
}
}
}
catch (Exception e)
{
response.Errors.Add(new ErrorResult
{
ErrorMessage = e.Message
});
}
return response;
}
public异步任务GetCompaniesByQuery()
{
var response=new GetCompanyResponse();
尝试
{
使用(var-conn=new-SqlConnection(_-configuration[“Settings:DBConn”]))
{
var cmd=conn.CreateCommand();
cmd.CommandType=CommandType.Text;
cmd.CommandText=“从dbo.tbl_companies中选择前1000名公司id、公司名称、邮政编码”;
conn.Open();
var reader=cmd.ExecuteReader();
while(reader.Read())
{
答复.公司.添加(新公司)
{
CompanyId=Convert.ToInt32(读卡器[“公司id”),
CompanyName=读取器[“公司名称”]。ToString(),
PostCode=读卡器[“PostCode”]。ToString()
});
}
}
}
捕获(例外e)
{
response.Errors.Add(新的ErrorResult
{
ErrorMessage=e.消息
});
}
返回响应;
}
我的控制器动作是:
public async Task<IActionResult> ByQuery()
{
var service = new TestService(_configuration);
var response = await service.GetCompaniesByQuery();
return View(response);
}
public async Task ByQuery()
{
var service=新的TestService(_配置);
var response=await service.getcompanysbyquery();
返回视图(响应);
}
VS中的上述方法一直告诉我无法返回响应,因为它无法转换。我做错了什么
Severity Code Description Project File Line Suppression State
Error CS0029 Cannot implicitly convert type 'TestApp.Models.GetCompanyResponse' to 'System.Threading.Tasks.Task<TestApp.Models.GetCompanyResponse>' TestApp C:\Working Copies\TestApp\TestApp\Services\TestService.cs 59 Active
严重性代码描述项目文件行抑制状态
错误CS0029无法将类型“TestApp.Models.GetCompanyResponse”隐式转换为“System.Threading.Tasks.Task”TestApp C:\Working Copies\TestApp\TestApp\Services\TestService.cs 59 Active
如果我试图提取任务中严格处理响应POCO的公司属性的元素,如下所示:
public async Task<IActionResult> ByQuery()
{
var service = new TestService(_configuration);
var response = new GetCompanyResponse();
response.Companies = (await service.GetCompaniesByQuery()).ToList();
return View(response);
}
public async Task<IEnumerable<Company>> GetCompaniesByQuery()
{
var response = new List<Company>();
try
{
using (var conn = new SqlConnection(_configuration["Settings:DBConn"]))
{
var cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT TOP (1000) company_id, company_name, postcode FROM dbo.tbl_companies";
conn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
response.Add(new Company
{
CompanyId = Convert.ToInt32(reader["company_id"]),
CompanyName = reader["company_name"].ToString(),
PostCode = reader["postcode"].ToString()
});
}
}
}
catch (Exception e)
{
//not implemented yet
}
await Task.WhenAll((IEnumerable<Task>)response);
return response;
}
public async Task ByQuery()
{
var service=新的TestService(_配置);
var response=new GetCompanyResponse();
response.companys=(wait service.getcompanysbyquery()).ToList();
返回视图(响应);
}
公共异步任务GetCompaniesByQuery()
{
var response=newlist();
尝试
{
使用(var-conn=new-SqlConnection(_-configuration[“Settings:DBConn”]))
{
var cmd=conn.CreateCommand();
cmd.CommandType=CommandType.Text;
cmd.CommandText=“从dbo.tbl_companies中选择前1000名公司id、公司名称、邮政编码”;
conn.Open();
var reader=cmd.ExecuteReader();
while(reader.Read())
{
答复.添加(新公司)
{
CompanyId=Convert.ToInt32(读卡器[“公司id”),
CompanyName=读取器[“公司名称”]。ToString(),
PostCode=读卡器[“PostCode”]。ToString()
});
}
}
}
捕获(例外e)
{
//尚未实施
}
等待任务。WhenAll((IEnumerable)响应);
返回响应;
}
当VS停止抱怨它时,当代码运行时,我开始运行无效的强制转换错误
InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List`1[TestApp.Models.Company]' to type 'System.Collections.Generic.IEnumerable`1[System.Threading.Tasks.Task]'.
TestApp.Services.TestService.GetCompaniesByQuery() in TestService.cs
+
await Task.WhenAll((IEnumerable<Task>)response);
TestApp.Controllers.HomeController.ByQuery() in HomeController.cs
+
response.Companies = (await service.GetCompaniesByQuery()).ToList();
InvalidCastException:无法将“System.Collections.Generic.List`1[TestApp.Models.Company]”类型的对象强制转换为“System.Collections.Generic.IEnumerable`1[System.Threading.Tasks.Task]”。
TestService.cs中的TestApp.Services.TestService.GetCompanyByQuery()
+
等待任务。WhenAll((IEnumerable)响应);
HomeController.cs中的TestApp.Controller.HomeController.ByQuery()
+
response.companys=(wait service.getcompanysbyquery()).ToList();
当我所看到的例子做了与上面完全相同的事情时,我不明白为什么这是原因。我在这里没有理解什么?为什么要编写异步方法而不调用其中的任何异步代码?至少使用
ExecuteReaderAsync
“VS中的上述方法一直告诉我,我无法返回响应,因为它无法转换。”请编辑您的问题,以包含行给出的实际编译器错误,因为您发布的代码看起来很好。“为了释放UI”-web应用程序不是这样工作的。在发送HTTP响应之前,UI不会对服务器上发生的事情做出任何响应。异步控制器操作的要点是释放服务器上的线程以处理其他工作。您将获得可伸缩性(假设您正在进行适当的异步调用,例如ExecuteReaderAsync),但在处理单个请求的速度稍微慢一点的情况下进行权衡。C#和AJAX中的async
功能互不相关。@DavidHirst在ASP.Net上下文中,async
操作方法的目的是释放当前线程池线程以服务于其他HTTP r